From 8f38e3f76eb8e931f6095d7c8953f14585c1a83c Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Fri, 16 Dec 2016 12:47:34 +0100 Subject: [PATCH] template automaton run algorithms --- alib2algo/src/automaton/run/Accept.cpp | 81 +-- alib2algo/src/automaton/run/Accept.h | 108 +++- alib2algo/src/automaton/run/Occurrences.cpp | 53 +- alib2algo/src/automaton/run/Occurrences.h | 71 ++- alib2algo/src/automaton/run/Result.cpp | 77 +-- alib2algo/src/automaton/run/Result.h | 87 ++- alib2algo/src/automaton/run/Run.cpp | 570 ------------------ alib2algo/src/automaton/run/Run.h | 606 +++++++++++++++++++- alib2algo/src/automaton/run/Translate.cpp | 15 - alib2algo/src/automaton/run/Translate.h | 20 +- 10 files changed, 863 insertions(+), 825 deletions(-) delete mode 100644 alib2algo/src/automaton/run/Run.cpp diff --git a/alib2algo/src/automaton/run/Accept.cpp b/alib2algo/src/automaton/run/Accept.cpp index b6b6d4cf93..9252ee6c4c 100644 --- a/alib2algo/src/automaton/run/Accept.cpp +++ b/alib2algo/src/automaton/run/Accept.cpp @@ -6,20 +6,6 @@ */ #include "Accept.h" -#include "Run.h" -#include <automaton/FSM/DFA.h> -#include <automaton/FSM/NFA.h> -#include <automaton/TA/DFTA.h> -#include <automaton/TA/NFTA.h> -#include <automaton/PDA/InputDrivenDPDA.h> -#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 { @@ -37,79 +23,14 @@ bool Accept::accept ( const automaton::Automaton & automaton, const tree::Ranked return dispatch ( automaton.getData ( ), tree ); } -bool Accept::accept ( const automaton::DFA<> & automaton, const string::LinearString < > & string ) { - std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, string ); - - return std::get < 0 > ( res ) && automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ); -} - -auto AcceptDFALinearString = Accept::RegistratorWrapper < bool, automaton::DFA<>, string::LinearString < > > ( Accept::accept ); - -bool Accept::accept ( const automaton::NFA < > & automaton, const string::LinearString < > & string ) { - std::tuple < bool, std::set < label::Label >, std::set < unsigned > > res = Run::calculateStates ( automaton, string ); - - return std::get < 0 > ( res ) && std::any_of ( std::get < 1 > ( res ).begin ( ), std::get < 1 > ( res ).end ( ), [&] ( const label::Label & state ) { - return automaton.getFinalStates ( ).count ( state ); - } ); -} - +auto AcceptDFALinearString = Accept::RegistratorWrapper < bool, automaton::DFA < >, string::LinearString < > > ( Accept::accept ); auto AcceptNFALinearString = Accept::RegistratorWrapper < bool, automaton::NFA < > , string::LinearString < > > ( Accept::accept ); - -bool Accept::accept ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree ) { - std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, tree ); - - return std::get < 0 > ( res ) && automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ); -} - auto AcceptDFTARankedTree = Accept::RegistratorWrapper < bool, automaton::DFTA < >, tree::RankedTree < > > ( Accept::accept ); - -bool Accept::accept ( const automaton::NFTA < > & automaton, const tree::RankedTree < > & tree ) { - std::tuple < bool, std::set < label::Label >, std::set < unsigned > > res = Run::calculateStates ( automaton, tree ); - - return std::get < 0 > ( res ) && std::any_of ( std::get < 1 > ( res ).begin ( ), std::get < 1 > ( res ).end ( ), [&] ( const label::Label & state ) { - return automaton.getFinalStates ( ).count ( state ); - } ); -} - auto AcceptNFTARankedTree = Accept::RegistratorWrapper < bool, automaton::NFTA < >, tree::RankedTree < > > ( Accept::accept ); - -bool Accept::accept ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string ) { - std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string ); - - return std::get < 0 > ( res ) && ( automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ) || ( automaton.getFinalStates ( ).size ( ) == 0 && std::get < 3 > ( res ).size ( ) == 0 ) ); -} - auto AcceptInputDrivenDPDALinearString = Accept::RegistratorWrapper < bool, automaton::InputDrivenDPDA < >, string::LinearString < > > ( Accept::accept ); - -bool Accept::accept ( const automaton::VisiblyPushdownDPDA < > & automaton, const string::LinearString < > & string ) { - std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string ); - - return std::get < 0 > ( res ) && automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ); -} - auto AcceptVisiblyPushdownDPDALinearString = Accept::RegistratorWrapper < bool, automaton::VisiblyPushdownDPDA < >, string::LinearString < > > ( Accept::accept ); - -bool Accept::accept ( const automaton::RealTimeHeightDeterministicDPDA < > & automaton, const string::LinearString < > & string ) { - std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string ); - - return std::get < 0 > ( res ) && automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ); -} - auto AcceptRealTimeHeightDeterministicDPDALinearString = Accept::RegistratorWrapper < bool, automaton::RealTimeHeightDeterministicDPDA < >, string::LinearString < > > ( Accept::accept ); - -bool Accept::accept ( const automaton::DPDA < > & automaton, const string::LinearString < > & string ) { - std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string ); - - return std::get < 0 > ( res ) && ( automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ) || ( automaton.getFinalStates ( ).size ( ) == 0 && std::get < 3 > ( res ).size ( ) == 0 ) ); -} - 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 < label::Label >, 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 */ diff --git a/alib2algo/src/automaton/run/Accept.h b/alib2algo/src/automaton/run/Accept.h index 4da0f7044d..172aec9a3e 100644 --- a/alib2algo/src/automaton/run/Accept.h +++ b/alib2algo/src/automaton/run/Accept.h @@ -15,6 +15,21 @@ #include <string/LinearString.h> #include <tree/ranked/RankedTree.h> +#include "Run.h" +#include <automaton/FSM/DFA.h> +#include <automaton/FSM/NFA.h> +#include <automaton/TA/DFTA.h> +#include <automaton/TA/NFTA.h> +#include <automaton/PDA/InputDrivenDPDA.h> +#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 { namespace run { @@ -29,18 +44,93 @@ public: 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::DFTA < > & automaton, const tree::RankedTree < > & tree ); - static bool accept ( const automaton::NFTA < > & automaton, const tree::RankedTree < > & tree ); - static bool accept ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string ); - 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 ); + template < class SymbolType, class StateType > + static bool accept ( const automaton::DFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class StateType > + static bool accept ( const automaton::NFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class RankType, class StateType > + static bool accept ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree ); + template < class SymbolType, class RankType, class StateType > + static bool accept ( const automaton::NFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree ); + template < class SymbolType, class StateType > + static bool accept ( const automaton::InputDrivenDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class StateType > + static bool accept ( const automaton::VisiblyPushdownDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class EpsilonType, class StateType > + static bool accept ( const automaton::RealTimeHeightDeterministicDPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class EpsilonType, class StateType > + static bool accept ( const automaton::DPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class EpsilonType, class StateType > + static bool accept ( const automaton::NPDTA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ); }; +template < class SymbolType, class StateType > +bool Accept::accept ( const automaton::DFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, StateType, std::set < unsigned > > res = Run::calculateState ( automaton, string ); + + return std::get < 0 > ( res ) && automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ); +} + +template < class SymbolType, class StateType > +bool Accept::accept ( const automaton::NFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, std::set < StateType >, std::set < unsigned > > res = Run::calculateStates ( automaton, string ); + + return std::get < 0 > ( res ) && std::any_of ( std::get < 1 > ( res ).begin ( ), std::get < 1 > ( res ).end ( ), [&] ( const StateType & state ) { + return automaton.getFinalStates ( ).count ( state ); + } ); +} + +template < class SymbolType, class RankType, class StateType > +bool Accept::accept ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree ) { + std::tuple < bool, StateType, std::set < unsigned > > res = Run::calculateState ( automaton, tree ); + + return std::get < 0 > ( res ) && automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ); +} + +template < class SymbolType, class RankType, class StateType > +bool Accept::accept ( const automaton::NFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree ) { + std::tuple < bool, std::set < StateType >, std::set < unsigned > > res = Run::calculateStates ( automaton, tree ); + + return std::get < 0 > ( res ) && std::any_of ( std::get < 1 > ( res ).begin ( ), std::get < 1 > ( res ).end ( ), [&] ( const StateType & state ) { + return automaton.getFinalStates ( ).count ( state ); + } ); +} + +template < class SymbolType, class StateType > +bool Accept::accept ( const automaton::InputDrivenDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > res = Run::calculateState ( automaton, string ); + + return std::get < 0 > ( res ) && ( automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ) || ( automaton.getFinalStates ( ).size ( ) == 0 && std::get < 3 > ( res ).size ( ) == 0 ) ); +} + +template < class SymbolType, class StateType > +bool Accept::accept ( const automaton::VisiblyPushdownDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > res = Run::calculateState ( automaton, string ); + + return std::get < 0 > ( res ) && automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ); +} + +template < class SymbolType, class EpsilonType, class StateType > +bool Accept::accept ( const automaton::RealTimeHeightDeterministicDPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > res = Run::calculateState ( automaton, string ); + + return std::get < 0 > ( res ) && automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ); +} + +template < class SymbolType, class EpsilonType, class StateType > +bool Accept::accept ( const automaton::DPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > res = Run::calculateState ( automaton, string ); + + return std::get < 0 > ( res ) && ( automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ) || ( automaton.getFinalStates ( ).size ( ) == 0 && std::get < 3 > ( res ).size ( ) == 0 ) ); +} + +template < class SymbolType, class EpsilonType, class StateType > +bool Accept::accept ( const automaton::NPDTA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, std::set < StateType >, std::set < std::vector < SymbolType > > > res = Run::calculateStates ( automaton, string ); + return std::get<0>(res); +} + } /* namespace run */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/run/Occurrences.cpp b/alib2algo/src/automaton/run/Occurrences.cpp index a3b38aa6fa..ef7b2f57bd 100644 --- a/alib2algo/src/automaton/run/Occurrences.cpp +++ b/alib2algo/src/automaton/run/Occurrences.cpp @@ -6,16 +6,6 @@ */ #include "Occurrences.h" -#include "Run.h" -#include <automaton/FSM/DFA.h> -#include <automaton/FSM/NFA.h> -#include <automaton/TA/DFTA.h> -#include <automaton/PDA/InputDrivenDPDA.h> -#include <automaton/PDA/VisiblyPushdownDPDA.h> -#include <automaton/PDA/RealTimeHeightDeterministicDPDA.h> -#include <automaton/PDA/DPDA.h> - -#include <deque> namespace automaton { @@ -33,52 +23,11 @@ std::set < unsigned > Occurrences::occurrences ( const automaton::Automaton & au return dispatch ( automaton.getData ( ), tree ); } -std::set < unsigned > Occurrences::occurrences ( const automaton::DFA < > & automaton, const string::LinearString < > & string ) { - std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, string ); - - return std::get < 2 > ( res ); -} - -auto OccurrencesDFALinearString = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::DFA<>, string::LinearString < > > ( Occurrences::occurrences ); - -std::set < unsigned > Occurrences::occurrences ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree ) { - std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, tree ); - - return std::get < 2 > ( res ); -} - +auto OccurrencesDFALinearString = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::DFA < >, string::LinearString < > > ( Occurrences::occurrences ); auto OccurrencesDFTARankedTree = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::DFTA < >, tree::RankedTree < > > ( Occurrences::occurrences ); - -std::set < unsigned > Occurrences::occurrences ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string ) { - std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string ); - - return std::get < 2 > ( res ); -} - auto OccurrencesInputDrivenDPDALinearString = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::InputDrivenDPDA < >, string::LinearString < > > ( Occurrences::occurrences ); - -std::set < unsigned > Occurrences::occurrences ( const automaton::VisiblyPushdownDPDA < > & automaton, const string::LinearString < > & string ) { - std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string ); - - return std::get < 2 > ( res ); -} - auto OccurrencesVisiblyPushdownDPDALinearString = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::VisiblyPushdownDPDA < >, string::LinearString < > > ( Occurrences::occurrences ); - -std::set < unsigned > Occurrences::occurrences ( const automaton::RealTimeHeightDeterministicDPDA < > & automaton, const string::LinearString < > & string ) { - std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string ); - - return std::get < 2 > ( res ); -} - auto OccurrencesRealTimeHeightDeterministicDPDALinearString = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::RealTimeHeightDeterministicDPDA < >, string::LinearString < > > ( Occurrences::occurrences ); - -std::set < unsigned > Occurrences::occurrences ( const automaton::DPDA < > & automaton, const string::LinearString < > & string ) { - std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string ); - - return std::get < 2 > ( res ); -} - auto OccurrencesDPDALinearString = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::DPDA < >, string::LinearString < > > ( Occurrences::occurrences ); } /* namespace run */ diff --git a/alib2algo/src/automaton/run/Occurrences.h b/alib2algo/src/automaton/run/Occurrences.h index ba6db00688..a95b4f913e 100644 --- a/alib2algo/src/automaton/run/Occurrences.h +++ b/alib2algo/src/automaton/run/Occurrences.h @@ -15,6 +15,17 @@ #include <string/LinearString.h> #include <tree/ranked/RankedTree.h> +#include "Run.h" +#include <automaton/FSM/DFA.h> +#include <automaton/FSM/NFA.h> +#include <automaton/TA/DFTA.h> +#include <automaton/PDA/InputDrivenDPDA.h> +#include <automaton/PDA/VisiblyPushdownDPDA.h> +#include <automaton/PDA/RealTimeHeightDeterministicDPDA.h> +#include <automaton/PDA/DPDA.h> + +#include <deque> + namespace automaton { namespace run { @@ -29,15 +40,63 @@ public: 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::DFTA < > & automaton, const tree::RankedTree < > & tree ); - static std::set < unsigned > occurrences ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string ); - static std::set < unsigned > occurrences ( const automaton::VisiblyPushdownDPDA < > & automaton, const string::LinearString < > & string ); - static std::set < unsigned > occurrences ( const automaton::RealTimeHeightDeterministicDPDA < > & automaton, const string::LinearString < > & string ); - static std::set < unsigned > occurrences ( const automaton::DPDA < > & automaton, const string::LinearString < > & string ); + template < class SymbolType, class StateType > + static std::set < unsigned > occurrences ( const automaton::DFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class RankType, class StateType > + static std::set < unsigned > occurrences ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree ); + template < class SymbolType, class StateType > + static std::set < unsigned > occurrences ( const automaton::InputDrivenDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class StateType > + static std::set < unsigned > occurrences ( const automaton::VisiblyPushdownDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class EpsilonType, class StateType > + static std::set < unsigned > occurrences ( const automaton::RealTimeHeightDeterministicDPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class EpsilonType, class StateType > + static std::set < unsigned > occurrences ( const automaton::DPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ); }; +template < class SymbolType, class StateType > +std::set < unsigned > Occurrences::occurrences ( const automaton::DFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, StateType, std::set < unsigned > > res = Run::calculateState ( automaton, string ); + + return std::get < 2 > ( res ); +} + +template < class SymbolType, class RankType, class StateType > +std::set < unsigned > Occurrences::occurrences ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree ) { + std::tuple < bool, StateType, std::set < unsigned > > res = Run::calculateState ( automaton, tree ); + + return std::get < 2 > ( res ); +} + +template < class SymbolType, class StateType > +std::set < unsigned > Occurrences::occurrences ( const automaton::InputDrivenDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > res = Run::calculateState ( automaton, string ); + + return std::get < 2 > ( res ); +} + +template < class SymbolType, class StateType > +std::set < unsigned > Occurrences::occurrences ( const automaton::VisiblyPushdownDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > res = Run::calculateState ( automaton, string ); + + return std::get < 2 > ( res ); +} + +template < class SymbolType, class EpsilonType, class StateType > +std::set < unsigned > Occurrences::occurrences ( const automaton::RealTimeHeightDeterministicDPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > res = Run::calculateState ( automaton, string ); + + return std::get < 2 > ( res ); +} + +template < class SymbolType, class EpsilonType, class StateType > +std::set < unsigned > Occurrences::occurrences ( const automaton::DPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > res = Run::calculateState ( automaton, string ); + + return std::get < 2 > ( res ); +} + } /* namespace run */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/run/Result.cpp b/alib2algo/src/automaton/run/Result.cpp index e91d7be414..f6bbb9005c 100644 --- a/alib2algo/src/automaton/run/Result.cpp +++ b/alib2algo/src/automaton/run/Result.cpp @@ -6,84 +6,21 @@ */ #include "Result.h" -#include "Run.h" -#include <automaton/FSM/DFA.h> -#include <automaton/TA/DFTA.h> -#include <automaton/PDA/InputDrivenDPDA.h> -#include <automaton/PDA/VisiblyPushdownDPDA.h> -#include <automaton/PDA/RealTimeHeightDeterministicDPDA.h> -#include <automaton/PDA/DPDA.h> -#include <label/LabelSetLabel.h> - -#include <deque> namespace automaton { namespace run { -label::Label Result::result ( const automaton::Automaton & automaton, const alib::Object & object, const label::Label & failLabel ) { +DefaultStateType Result::result ( const automaton::Automaton & automaton, const alib::Object & object, const DefaultStateType & failLabel ) { return dispatch ( automaton.getData ( ), object.getData ( ), failLabel ); } -label::Label Result::result ( const automaton::DFA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel ) { - std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, string ); - - if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ); - - return failLabel; -} - -auto ResultDFALinearString = Result::RegistratorWrapper < label::Label, automaton::DFA<>, string::LinearString < > > ( Result::result ); - -label::Label Result::result ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree, const label::Label & failLabel ) { - std::tuple < bool, label::Label, std::set < unsigned > > res = Run::calculateState ( automaton, tree ); - - if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ); - - return failLabel; -} - -auto ResultDFTARankedTree = Result::RegistratorWrapper < label::Label, automaton::DFTA < >, tree::RankedTree < > > ( Result::result ); - -label::Label Result::result ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel ) { - std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string ); - - if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ); - - return failLabel; -} - -auto ResultInputDrivenDPDALinearString = Result::RegistratorWrapper < label::Label, automaton::InputDrivenDPDA < >, string::LinearString < > > ( Result::result ); - -label::Label Result::result ( const automaton::VisiblyPushdownDPDA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel ) { - std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string ); - - if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ); - - return failLabel; -} - -auto ResultVisiblyPushdownDPDALinearString = Result::RegistratorWrapper < label::Label, automaton::VisiblyPushdownDPDA < >, string::LinearString < > > ( Result::result ); - -label::Label Result::result ( const automaton::RealTimeHeightDeterministicDPDA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel ) { - std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string ); - - if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ); - - return failLabel; -} - -auto ResultRealTimeHeightDeterministicDPDALinearString = Result::RegistratorWrapper < label::Label, automaton::RealTimeHeightDeterministicDPDA < >, string::LinearString < > > ( Result::result ); - -label::Label Result::result ( const automaton::DPDA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel ) { - std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > res = Run::calculateState ( automaton, string ); - - if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ); - - return failLabel; -} - -auto ResultDPDALinearString = Result::RegistratorWrapper < label::Label, automaton::DPDA < >, string::LinearString < > > ( Result::result ); +auto ResultDFALinearString = Result::RegistratorWrapper < DefaultStateType, automaton::DFA < >, string::LinearString < > > ( Result::result ); +auto ResultDFTARankedTree = Result::RegistratorWrapper < DefaultStateType, automaton::DFTA < >, tree::RankedTree < > > ( Result::result ); +auto ResultInputDrivenDPDALinearString = Result::RegistratorWrapper < DefaultStateType, automaton::InputDrivenDPDA < >, string::LinearString < > > ( Result::result ); +auto ResultVisiblyPushdownDPDALinearString = Result::RegistratorWrapper < DefaultStateType, automaton::VisiblyPushdownDPDA < >, string::LinearString < > > ( Result::result ); +auto ResultRealTimeHeightDeterministicDPDALinearString = Result::RegistratorWrapper < DefaultStateType, automaton::RealTimeHeightDeterministicDPDA < >, string::LinearString < > > ( Result::result ); +auto ResultDPDALinearString = Result::RegistratorWrapper < DefaultStateType, automaton::DPDA < >, string::LinearString < > > ( Result::result ); } /* namespace run */ diff --git a/alib2algo/src/automaton/run/Result.h b/alib2algo/src/automaton/run/Result.h index 26117df7b7..bc6341fe7d 100644 --- a/alib2algo/src/automaton/run/Result.h +++ b/alib2algo/src/automaton/run/Result.h @@ -17,27 +17,98 @@ #include <tree/ranked/RankedTree.h> #include <label/FailStateLabel.h> +#include "Run.h" +#include <automaton/FSM/DFA.h> +#include <automaton/TA/DFTA.h> +#include <automaton/PDA/InputDrivenDPDA.h> +#include <automaton/PDA/VisiblyPushdownDPDA.h> +#include <automaton/PDA/RealTimeHeightDeterministicDPDA.h> +#include <automaton/PDA/DPDA.h> +#include <label/LabelSetLabel.h> + +#include <deque> + namespace automaton { namespace run { -class Result : public std::DoubleDispatch < Result, label::Label, const automaton::AutomatonBase &, const alib::ObjectBase &, const label::Label & > { +class Result : public std::DoubleDispatch < Result, DefaultStateType, const automaton::AutomatonBase &, const alib::ObjectBase &, const DefaultStateType & > { public: /** * Performs conversion. * @return left regular grammar equivalent to source automaton. */ - static label::Label result ( const automaton::Automaton & automaton, const alib::Object & object, const label::Label & failLabel = label::FailStateLabel::instance < label::Label > ( ) ); + static DefaultStateType result ( const automaton::Automaton & automaton, const alib::Object & object, const DefaultStateType & failLabel = label::FailStateLabel::instance < DefaultStateType > ( ) ); - static label::Label result ( const automaton::DFA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel = label::FailStateLabel::instance < label::Label > ( ) ); - static label::Label result ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree, const label::Label & failLabel = label::FailStateLabel::instance < label::Label > ( ) ); - static label::Label result ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel = label::FailStateLabel::instance < label::Label > ( ) ); - static label::Label result ( const automaton::VisiblyPushdownDPDA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel = label::FailStateLabel::instance < label::Label > ( ) ); - static label::Label result ( const automaton::RealTimeHeightDeterministicDPDA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel = label::FailStateLabel::instance < label::Label > ( ) ); - static label::Label result ( const automaton::DPDA < > & automaton, const string::LinearString < > & string, const label::Label & failLabel = label::FailStateLabel::instance < label::Label > ( ) ); + template < class SymbolType, class StateType > + static StateType result ( const automaton::DFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string, const StateType & failLabel = label::FailStateLabel::instance < StateType > ( ) ); + template < class SymbolType, class RankType, class StateType > + static StateType result ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree, const StateType & failLabel = label::FailStateLabel::instance < StateType > ( ) ); + template < class SymbolType, class StateType > + static StateType result ( const automaton::InputDrivenDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string, const StateType & failLabel = label::FailStateLabel::instance < StateType > ( ) ); + template < class SymbolType, class StateType > + static StateType result ( const automaton::VisiblyPushdownDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string, const StateType & failLabel = label::FailStateLabel::instance < StateType > ( ) ); + template < class SymbolType, class EpsilonType, class StateType > + static StateType result ( const automaton::RealTimeHeightDeterministicDPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string, const StateType & failLabel = label::FailStateLabel::instance < StateType > ( ) ); + template < class SymbolType, class EpsilonType, class StateType > + static StateType result ( const automaton::DPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string, const StateType & failLabel = label::FailStateLabel::instance < StateType > ( ) ); }; +template < class SymbolType, class StateType > +StateType Result::result ( const automaton::DFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string, const StateType & failLabel ) { + std::tuple < bool, StateType, std::set < unsigned > > res = Run::calculateState ( automaton, string ); + + if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ); + + return failLabel; +} + +template < class SymbolType, class RankType, class StateType > +StateType Result::result ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree, const StateType & failLabel ) { + std::tuple < bool, StateType, std::set < unsigned > > res = Run::calculateState ( automaton, tree ); + + if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ); + + return failLabel; +} + +template < class SymbolType, class StateType > +StateType Result::result ( const automaton::InputDrivenDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string, const StateType & failLabel ) { + std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > res = Run::calculateState ( automaton, string ); + + if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ); + + return failLabel; +} + +template < class SymbolType, class StateType > +StateType Result::result ( const automaton::VisiblyPushdownDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string, const StateType & failLabel ) { + std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > res = Run::calculateState ( automaton, string ); + + if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ); + + return failLabel; +} + +template < class SymbolType, class EpsilonType, class StateType > +StateType Result::result ( const automaton::RealTimeHeightDeterministicDPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string, const StateType & failLabel ) { + std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > res = Run::calculateState ( automaton, string ); + + if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ); + + return failLabel; +} + +template < class SymbolType, class EpsilonType, class StateType > +StateType Result::result ( const automaton::DPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string, const StateType & failLabel ) { + std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > res = Run::calculateState ( automaton, string ); + + if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ); + + return failLabel; +} + } /* namespace run */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/run/Run.cpp b/alib2algo/src/automaton/run/Run.cpp deleted file mode 100644 index 10caa1614f..0000000000 --- a/alib2algo/src/automaton/run/Run.cpp +++ /dev/null @@ -1,570 +0,0 @@ -/* - * Accept.cpp - * - * Created on: 9. 2. 2014 - * Author: Jan Travnicek - */ - -#include "Run.h" -#include <automaton/FSM/DFA.h> -#include <automaton/FSM/NFA.h> -#include <automaton/TA/DFTA.h> -#include <automaton/TA/NFTA.h> -#include <automaton/PDA/InputDrivenDPDA.h> -#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 <label/FailStateLabel.h> - -#include <deque> -#include <algorithm> -#include <iterator> - -namespace automaton { - -namespace run { - -// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - -std::tuple < bool, label::Label, std::set < unsigned > > Run::calculateState ( const automaton::DFA < > & automaton, const string::LinearString < > & string ) { - bool res = true; - unsigned i = 0; - std::set < unsigned > occurrences; - label::Label state = automaton.getInitialState ( ); - - if ( automaton.getFinalStates ( ).count ( state ) ) - occurrences.insert ( i ); - - if ( common::GlobalData::verbose ) - std::clog << state << std::endl; - - for ( const alphabet::Symbol & symbol : string.getContent ( ) ) { - auto transition = automaton.getTransitions ( ).find ( std::make_pair ( state, symbol ) ); - - if ( transition == automaton.getTransitions ( ).end ( ) ) { - res = false; - break; - } - - state = transition->second; - i++; - - if ( automaton.getFinalStates ( ).count ( state ) ) - occurrences.insert ( i ); - - if ( common::GlobalData::verbose ) - std::clog << state << std::endl; - } - - return std::make_tuple ( res, state, occurrences ); -} - -// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - -std::tuple < bool, std::set < label::Label >, std::set < unsigned > > Run::calculateStates ( const automaton::NFA < > & automaton, const string::LinearString < > & string ) { - bool res = true; - unsigned i = 0; - std::set < unsigned > occurrences; - std::set < label::Label > states { - automaton.getInitialState ( ) - }; - - for ( const label::Label & state : states ) - if ( automaton.getFinalStates ( ).count ( state ) ) - occurrences.insert ( i ); - - if ( common::GlobalData::verbose ) - std::clog << states << std::endl; - - for ( const alphabet::Symbol & symbol : string.getContent ( ) ) { - std::set < label::Label > next; - - for ( const label::Label & state : states ) { - auto transitions = automaton.getTransitions ( ).find ( std::make_pair ( state, symbol ) ); - - if ( transitions == automaton.getTransitions ( ).end ( ) ) continue; - - next.insert ( transitions->second.begin ( ), transitions->second.end ( ) ); - } - - i++; - states = next; - - for ( const label::Label & state : states ) - if ( automaton.getFinalStates ( ).count ( state ) ) - occurrences.insert ( i ); - - if ( common::GlobalData::verbose ) - std::clog << states << std::endl; - } - - return std::make_tuple ( res, states, occurrences ); -} - -// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - -std::pair < bool, label::Label > Run::calculateState ( const automaton::DFTA < > & automaton, const std::tree < std::ranked_symbol < > > & node, std::set < unsigned > & occ, unsigned & i ) { - std::vector < label::Label > states; - - states.reserve ( ( size_t ) node.getData ( ).getRank ( ) ); - - unsigned tmp = i; - i++; - - bool sign = true; - - for ( const std::tree < std::ranked_symbol < > > & child : node.getChildren ( ) ) { - std::pair < bool, label::Label > res = calculateState ( automaton, child, occ, i ); - - if ( res.first == false ) - sign = false; - else - states.push_back ( res.second ); - } - - if ( !sign ) return std::make_pair ( false, label::FailStateLabel::instance < label::Label > ( ) ); - - const auto & it = automaton.getTransitions ( ).find ( std::make_pair ( node.getData ( ), states ) ); - - if ( it == automaton.getTransitions ( ).end ( ) ) return std::make_pair ( false, label::FailStateLabel::instance < label::Label > ( ) ); - - label::Label state = it->second; - - if ( automaton.getFinalStates ( ).count ( state ) ) occ.insert ( tmp ); - - if ( common::GlobalData::verbose ) - std::clog << state << std::endl; - - return std::make_pair ( true, state ); -} - -std::tuple < bool, label::Label, std::set < unsigned > > Run::calculateState ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree ) { - std::set < unsigned > occ; - unsigned i = 0; - std::pair < bool, label::Label > res = calculateState ( automaton, tree.getContent ( ), occ, i ); - - return std::make_tuple ( res.first, res.second, occ ); -} - -// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - -std::pair < bool, std::set < label::Label > > Run::calculateStates ( const automaton::NFTA < > & automaton, const std::tree < std::ranked_symbol < > > & node, std::set < unsigned > & occ, unsigned & i ) { - std::vector < std::set < label::Label > > resStates; - - resStates.reserve ( ( size_t ) node.getData ( ).getRank ( ) ); - - unsigned tmp = i; - i++; - - bool sign = true; - - for ( const std::tree < std::ranked_symbol < > > & child : node.getChildren ( ) ) { - std::pair < bool, std::set < label::Label > > childStates = calculateStates ( automaton, child, occ, i ); - - if ( childStates.second.empty ( ) ) - sign = false; - - resStates.push_back ( childStates.second ); - } - - std::set < label::Label > states; - - for ( const auto & transition : automaton.getTransitions ( ) ) { - if ( transition.first.first != node.getData ( ) ) - continue; - - unsigned rank = ( unsigned ) transition.first.first.getRank ( ); - unsigned j; - - for ( j = 0; j < rank; j++ ) - if ( !resStates[j].count ( transition.first.second[j] ) ) - break; - - if ( j == rank ) - states.insert ( transition.second.begin ( ), transition.second.end ( ) ); - } - - for ( const label::Label & state : states ) - if ( automaton.getFinalStates ( ).count ( state ) ) occ.insert ( tmp ); - - if ( common::GlobalData::verbose ) - std::clog << states << std::endl; - - return std::make_pair ( sign, states ); -} - -std::tuple < bool, std::set < label::Label >, std::set < unsigned > > Run::calculateStates ( const automaton::NFTA < > & automaton, const tree::RankedTree < > & tree ) { - std::set < unsigned > occ; - unsigned i = 0; - std::pair < bool, std::set < label::Label > > res = calculateStates ( automaton, tree.getContent ( ), occ, i ); - - return std::make_tuple ( res.first, res.second, occ ); -} - -// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - -bool Run::canPop ( const std::deque < alphabet::Symbol > & pushdownStore, const std::vector < alphabet::Symbol > & pop ) { - unsigned popSize = pop.size ( ); - unsigned pushdownStoreSize = pushdownStore.size ( ); - - if ( pushdownStoreSize < popSize ) return false; - - for ( unsigned i = 0; i < popSize; i++ ) - if ( pop[i] != pushdownStore[pushdownStoreSize - i - 1] ) - return false; - - return true; -} - -// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - -std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > Run::calculateState ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string ) { - label::Label state = automaton.getInitialState ( ); - std::deque < alphabet::Symbol > pushdownStore { - automaton.getInitialSymbol ( ) - }; - unsigned i = 0; - std::set < unsigned > occ; - bool res = true; - - if ( automaton.getFinalStates ( ).count ( state ) ) - occ.insert ( i ); - - if ( common::GlobalData::verbose ) - std::clog << state << std::endl; - - for ( const alphabet::Symbol & symbol : string.getContent ( ) ) { - auto transition = automaton.getTransitions ( ).find ( std::make_pair ( state, symbol ) ); - - if ( transition == automaton.getTransitions ( ).end ( ) ) { - res = false; - break; - } - - const std::pair < std::vector < alphabet::Symbol >, std::vector < alphabet::Symbol > > & operation = automaton.getPushdownStoreOperations ( ).find ( symbol )->second; - - if ( !canPop ( pushdownStore, operation.first ) ) { - res = false; - break; - } - - for ( unsigned j = 0; j < operation.first.size ( ); j++ ) pushdownStore.pop_back ( ); - - for ( const auto & push : std::make_reverse ( operation.second ) ) pushdownStore.push_back ( push ); - - state = transition->second; - i++; - - if ( automaton.getFinalStates ( ).count ( state ) ) - occ.insert ( i ); - - if ( common::GlobalData::verbose ) - std::clog << state << std::endl; - } - - return std::make_tuple ( res, state, occ, pushdownStore ); -} - -// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - -std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > Run::calculateState ( const automaton::VisiblyPushdownDPDA < > & automaton, const string::LinearString < > & string ) { - label::Label state = automaton.getInitialState ( ); - std::deque < alphabet::Symbol > pushdownStore { - automaton.getBottomOfTheStackSymbol ( ) - }; - unsigned i = 0; - std::set < unsigned > occ; - bool res = true; - - if ( automaton.getFinalStates ( ).count ( state ) ) - occ.insert ( i ); - - if ( common::GlobalData::verbose ) - std::clog << state << std::endl; - - for ( const alphabet::Symbol & symbol : string.getContent ( ) ) { - if ( automaton.getCallInputAlphabet ( ).count ( symbol ) ) { - auto transition = automaton.getCallTransitions ( ).find ( std::make_pair ( state, symbol ) ); - - if ( transition == automaton.getCallTransitions ( ).end ( ) ) { - res = false; - break; - } - - pushdownStore.push_back ( transition->second.second ); - state = transition->second.first; - } else if ( automaton.getReturnInputAlphabet ( ).count ( symbol ) ) { - auto transition = automaton.getReturnTransitions ( ).find ( std::make_tuple ( state, symbol, pushdownStore.back ( ) ) ); - - if ( transition == automaton.getReturnTransitions ( ).end ( ) ) { - res = false; - break; - } - - if ( pushdownStore.back ( ) != automaton.getBottomOfTheStackSymbol ( ) ) pushdownStore.pop_back ( ); - - state = transition->second; - } else if ( automaton.getLocalInputAlphabet ( ).count ( symbol ) ) { - auto transition = automaton.getLocalTransitions ( ).find ( std::make_pair ( state, symbol ) ); - - if ( transition == automaton.getLocalTransitions ( ).end ( ) ) { - res = false; - break; - } - - state = transition->second; - } else { - res = false; - break; - } - - i++; - - if ( automaton.getFinalStates ( ).count ( state ) ) - occ.insert ( i ); - - if ( common::GlobalData::verbose ) - std::clog << state << std::endl; - } - - return std::make_tuple ( res, state, occ, pushdownStore ); -} - -// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - -std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > Run::calculateState ( const automaton::RealTimeHeightDeterministicDPDA < > & automaton, const string::LinearString < > & string ) { - label::Label state = automaton.getInitialState ( ); - std::deque < alphabet::Symbol > pushdownStore { - automaton.getBottomOfTheStackSymbol ( ) - }; - unsigned i = 0; - std::set < unsigned > occ; - bool res = true; - - if ( automaton.getFinalStates ( ).count ( state ) ) - occ.insert ( i ); - - if ( common::GlobalData::verbose ) - std::clog << state << std::endl; - - for ( auto symbolIter = string.getContent ( ).begin ( ); symbolIter != string.getContent ( ).end ( ); ) { - - auto callTransition = automaton.getCallTransitions ( ).find ( std::make_pair ( state, * symbolIter ) ); - - if ( callTransition != automaton.getCallTransitions ( ).end ( ) ) { - symbolIter++; - i++; - } else { - callTransition = automaton.getCallTransitions ( ).find ( std::make_pair ( state, string::Epsilon < >::EPSILON ) ); - } - - if ( callTransition != automaton.getCallTransitions ( ).end ( ) ) { - pushdownStore.push_back ( callTransition->second.second ); - state = callTransition->second.first; - } else { - res = false; - } - - if ( !res ) { - auto returnTransition = automaton.getReturnTransitions ( ).find ( std::make_tuple ( state, * symbolIter, pushdownStore.back ( ) ) ); - - if ( returnTransition != automaton.getReturnTransitions ( ).end ( ) ) { - symbolIter++; - i++; - } else { - returnTransition = automaton.getReturnTransitions ( ).find ( std::make_tuple ( state, string::Epsilon < >::EPSILON, pushdownStore.back ( ) ) ); - } - - if ( returnTransition != automaton.getReturnTransitions ( ).end ( ) ) { - pushdownStore.pop_back ( ); - state = returnTransition->second; - } else { - res = false; - } - } - - if ( !res ) { - auto localTransition = automaton.getLocalTransitions ( ).find ( std::make_pair ( state, * symbolIter ) ); - - if ( localTransition != automaton.getLocalTransitions ( ).end ( ) ) { - symbolIter++; - i++; - } else { - localTransition = automaton.getLocalTransitions ( ).find ( std::make_pair ( state, string::Epsilon < >::EPSILON ) ); - } - - if ( localTransition != automaton.getLocalTransitions ( ).end ( ) ) - state = localTransition->second; - else - res = false; - } - - if ( automaton.getFinalStates ( ).count ( state ) ) - occ.insert ( i ); - - if ( common::GlobalData::verbose ) - std::clog << state << std::endl; - - if ( res == false ) - break; - } - - return std::make_tuple ( res, state, occ, pushdownStore ); -} - -// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - -std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > Run::calculateState ( const automaton::DPDA < > & automaton, const string::LinearString < > & string ) { - label::Label state = automaton.getInitialState ( ); - std::deque < alphabet::Symbol > pushdownStore { - automaton.getInitialSymbol ( ) - }; - unsigned i = 0; - std::set < unsigned > occ; - bool res = true; - - if ( automaton.getFinalStates ( ).count ( state ) ) - occ.insert ( i ); - - if ( common::GlobalData::verbose ) { - std::clog << "State : " << state << std::endl; - std::clog << "PushdownStore : " << pushdownStore << std::endl; - } - - for ( auto symbolIter = string.getContent ( ).begin ( ); symbolIter != string.getContent ( ).end ( ); ) { - auto transitions = automaton.getTransitionsFromState ( state ); - auto transition = transitions.begin ( ); - - for ( ; transition != transitions.end ( ); transition++ ) { - if ( ( std::get < 1 > ( transition->first ) != * symbolIter ) && !std::get < 1 > ( transition->first ).is < string::Epsilon < > > ( ) ) continue; - - if ( canPop ( pushdownStore, std::get < 2 > ( transition->first ) ) ) break; - } - - if ( transition == transitions.end ( ) ) { - res = false; - break; - } - - if ( common::GlobalData::verbose ) - std::clog << "Transition: " << * transition << std::endl; - - for ( unsigned j = 0; j < std::get < 2 > ( transition->first ).size ( ); j++ ) pushdownStore.pop_back ( ); - - for ( const auto & symbol : std::make_reverse ( transition->second.second ) ) pushdownStore.push_back ( symbol ); - - state = transition->second.first; - - if ( !std::get < 1 > ( transition->first ).is < string::Epsilon < > > ( ) ) { - i++; - symbolIter++; - } - - if ( automaton.getFinalStates ( ).count ( state ) ) - occ.insert ( i ); - - if ( common::GlobalData::verbose ) { - std::clog << "State: " << state << std::endl; - std::clog << "PushdownStore: " << pushdownStore << std::endl; - } - } - - return std::make_tuple ( res, state, occ, pushdownStore ); -} - -// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - -struct graphStructuredStack { - graphStructuredStack ( std::shared_ptr < graphStructuredStack > parent, alphabet::Symbol data ) : m_parent(parent), m_data(data) {} - std::shared_ptr < graphStructuredStack > m_parent; - alphabet::Symbol m_data; -}; - -std::tuple < bool, std::set < label::Label >, 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; - label::Label state = automaton . getInitialState (); - std::vector<alphabet::Symbol>::const_iterator symbolIter = string . getContent () . begin (); - std::shared_ptr < graphStructuredStack > stackNode = std::make_shared < graphStructuredStack > ( nullptr, * symbolIter ); - std::shared_ptr < graphStructuredStack > outputNode = std::make_shared < graphStructuredStack > ( nullptr, * symbolIter ); - - if ( automaton . getFinalStates () . count ( state ) ) { - occurrences . insert ( i ); - } - - std::deque < std::tuple < label::Label, std::vector<alphabet::Symbol>::const_iterator, std::shared_ptr < graphStructuredStack >, std::shared_ptr < graphStructuredStack > > > bftQueue; - auto configuration = std::make_tuple ( state, symbolIter, stackNode, outputNode ); - bftQueue . push_back ( configuration ); - - std::set < std::vector < alphabet::Symbol > > allOutputs; - std::set < label::Label > 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 -> m_parent == NULL ) { - res = true; - std::vector < alphabet::Symbol > output; - while ( outputNode->m_parent != NULL ) { - output . push_back ( outputNode->m_data ); - outputNode = outputNode -> m_parent; - } - std::reverse ( output.begin(), output.end() ); - allOutputs . insert ( output ); - } - continue; - } - - for ( const auto & transition : automaton . getTransitionsFromState ( state ) ) { - if ( std::get<1>(transition . first) != * symbolIter && ! std::get<1>(transition . first) . is<string::Epsilon < >>() ) - continue; - - const auto & pop = std::get<2>(transition . first); - std::shared_ptr < graphStructuredStack > stackNodeCopy = stackNode; - std::shared_ptr < graphStructuredStack > outputNodeCopy = outputNode; - - unsigned j = 0; - for ( ; j < pop . size (); j ++ ) { - if ( stackNodeCopy->m_parent == NULL || stackNodeCopy->m_data != pop . at (j) ) { - break; - } - stackNodeCopy = stackNodeCopy -> m_parent; - } - if ( j == pop . size () ) { - for ( const auto & elem : std::make_reverse ( std::get<1>(transition . second ) ) ) { - stackNodeCopy = std::make_shared < graphStructuredStack > ( stackNodeCopy, elem ); - } - for ( const auto & elem : std::get<2>(transition . second) ) { - outputNodeCopy = std::make_shared < graphStructuredStack > ( outputNodeCopy, elem ); - } - - 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 ); - } - } - } - - 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 82ec3157a0..96e4bec98a 100644 --- a/alib2algo/src/automaton/run/Run.h +++ b/alib2algo/src/automaton/run/Run.h @@ -12,30 +12,608 @@ #include <automaton/AutomatonFeatures.h> #include <string/LinearString.h> #include <tree/ranked/RankedTree.h> -#include <alphabet/Symbol.h> -#include <label/Label.h> + +#include <automaton/FSM/DFA.h> +#include <automaton/FSM/NFA.h> +#include <automaton/TA/DFTA.h> +#include <automaton/TA/NFTA.h> +#include <automaton/PDA/InputDrivenDPDA.h> +#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 <label/FailStateLabel.h> + +#include <deque> +#include <algorithm> +#include <iterator> namespace automaton { namespace run { class Run { - static std::pair < bool, label::Label > calculateState ( const automaton::DFTA < > & automaton, const std::tree < std::ranked_symbol < > > & node, std::set < unsigned > & occ, unsigned & i ); - static std::pair < bool, std::set < label::Label > > calculateStates ( const automaton::NFTA < > & automaton, const std::tree < std::ranked_symbol < > > & node, std::set < unsigned > & occ, unsigned & i ); - static bool canPop ( const std::deque < alphabet::Symbol > & pushdownStore, const std::vector < alphabet::Symbol > & pop ); + template < class SymbolType, class RankType, class StateType > + static std::pair < bool, StateType > calculateState ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const std::tree < std::ranked_symbol < SymbolType, RankType > > & node, std::set < unsigned > & occ, unsigned & i ); + template < class SymbolType, class RankType, class StateType > + static std::pair < bool, std::set < StateType > > calculateStates ( const automaton::NFTA < SymbolType, RankType, StateType > & automaton, const std::tree < std::ranked_symbol < SymbolType, RankType > > & node, std::set < unsigned > & occ, unsigned & i ); + template < class SymbolType > + static bool canPop ( const std::deque < SymbolType > & pushdownStore, const std::vector < SymbolType > & pop ); public: - static std::tuple < bool, label::Label, std::set < unsigned > > calculateState ( const automaton::DFA < > & automaton, const string::LinearString < > & string ); - static std::tuple < bool, std::set < label::Label >, std::set < unsigned > > calculateStates ( const automaton::NFA < > & automaton, const string::LinearString < > & string ); - static std::tuple < bool, label::Label, std::set < unsigned > > calculateState ( const automaton::DFTA < > & automaton, const tree::RankedTree < > & tree ); - static std::tuple < bool, std::set < label::Label >, std::set < unsigned > > calculateStates ( const automaton::NFTA < > & automaton, const tree::RankedTree < > & tree ); - static std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > calculateState ( const automaton::InputDrivenDPDA < > & automaton, const string::LinearString < > & string ); - static std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > calculateState ( const automaton::VisiblyPushdownDPDA < > & automaton, const string::LinearString < > & string ); - static std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > calculateState ( const automaton::RealTimeHeightDeterministicDPDA < > & automaton, const string::LinearString < > & string ); - static std::tuple < bool, label::Label, std::set < unsigned >, std::deque < alphabet::Symbol > > calculateState ( const automaton::DPDA < > & automaton, const string::LinearString < > & string ); - static std::tuple < bool, std::set < label::Label >, std::set < std::vector < alphabet::Symbol > > > calculateStates ( const automaton::NPDTA < > & automaton, const string::LinearString < > & string ); + template < class SymbolType, class StateType > + static std::tuple < bool, StateType, std::set < unsigned > > calculateState ( const automaton::DFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class StateType > + static std::tuple < bool, std::set < StateType >, std::set < unsigned > > calculateStates ( const automaton::NFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class RankType, class StateType > + static std::tuple < bool, StateType, std::set < unsigned > > calculateState ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree ); + template < class SymbolType, class RankType, class StateType > + static std::tuple < bool, std::set < StateType >, std::set < unsigned > > calculateStates ( const automaton::NFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree ); + template < class SymbolType, class StateType > + static std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > calculateState ( const automaton::InputDrivenDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class StateType > + static std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > calculateState ( const automaton::VisiblyPushdownDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class EpsilonType, class StateType > + static std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > calculateState ( const automaton::RealTimeHeightDeterministicDPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class EpsilonType, class StateType > + static std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > calculateState ( const automaton::DPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class EpsilonType, class StateType > + static std::tuple < bool, std::set < StateType >, std::set < std::vector < SymbolType > > > calculateStates ( const automaton::NPDTA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ); }; +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +template < class SymbolType, class StateType > +std::tuple < bool, StateType, std::set < unsigned > > Run::calculateState ( const automaton::DFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + bool res = true; + unsigned i = 0; + std::set < unsigned > occurrences; + StateType state = automaton.getInitialState ( ); + + if ( automaton.getFinalStates ( ).count ( state ) ) + occurrences.insert ( i ); + + if ( common::GlobalData::verbose ) + std::clog << state << std::endl; + + for ( const SymbolType & symbol : string.getContent ( ) ) { + auto transition = automaton.getTransitions ( ).find ( std::make_pair ( state, symbol ) ); + + if ( transition == automaton.getTransitions ( ).end ( ) ) { + res = false; + break; + } + + state = transition->second; + i++; + + if ( automaton.getFinalStates ( ).count ( state ) ) + occurrences.insert ( i ); + + if ( common::GlobalData::verbose ) + std::clog << state << std::endl; + } + + return std::make_tuple ( res, state, occurrences ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +template < class SymbolType, class StateType > +std::tuple < bool, std::set < StateType >, std::set < unsigned > > Run::calculateStates ( const automaton::NFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + bool res = true; + unsigned i = 0; + std::set < unsigned > occurrences; + std::set < StateType > states { + automaton.getInitialState ( ) + }; + + for ( const StateType & state : states ) + if ( automaton.getFinalStates ( ).count ( state ) ) + occurrences.insert ( i ); + + if ( common::GlobalData::verbose ) + std::clog << states << std::endl; + + for ( const SymbolType & symbol : string.getContent ( ) ) { + std::set < StateType > next; + + for ( const StateType & state : states ) { + auto transitions = automaton.getTransitions ( ).find ( std::make_pair ( state, symbol ) ); + + if ( transitions == automaton.getTransitions ( ).end ( ) ) continue; + + next.insert ( transitions->second.begin ( ), transitions->second.end ( ) ); + } + + i++; + states = next; + + for ( const StateType & state : states ) + if ( automaton.getFinalStates ( ).count ( state ) ) + occurrences.insert ( i ); + + if ( common::GlobalData::verbose ) + std::clog << states << std::endl; + } + + return std::make_tuple ( res, states, occurrences ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +template < class SymbolType, class RankType, class StateType > +std::pair < bool, StateType > Run::calculateState ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const std::tree < std::ranked_symbol < SymbolType, RankType > > & node, std::set < unsigned > & occ, unsigned & i ) { + std::vector < StateType > states; + + states.reserve ( ( size_t ) node.getData ( ).getRank ( ) ); + + unsigned tmp = i; + i++; + + bool sign = true; + + for ( const std::tree < std::ranked_symbol < SymbolType, RankType > > & child : node.getChildren ( ) ) { + std::pair < bool, StateType > res = calculateState ( automaton, child, occ, i ); + + if ( res.first == false ) + sign = false; + else + states.push_back ( res.second ); + } + + if ( !sign ) return std::make_pair ( false, label::FailStateLabel::instance < StateType > ( ) ); + + const auto & it = automaton.getTransitions ( ).find ( std::make_pair ( node.getData ( ), states ) ); + + if ( it == automaton.getTransitions ( ).end ( ) ) return std::make_pair ( false, label::FailStateLabel::instance < StateType > ( ) ); + + StateType state = it->second; + + if ( automaton.getFinalStates ( ).count ( state ) ) occ.insert ( tmp ); + + if ( common::GlobalData::verbose ) + std::clog << state << std::endl; + + return std::make_pair ( true, state ); +} + +template < class SymbolType, class RankType, class StateType > +std::tuple < bool, StateType, std::set < unsigned > > Run::calculateState ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree ) { + std::set < unsigned > occ; + unsigned i = 0; + std::pair < bool, StateType > res = calculateState ( automaton, tree.getContent ( ), occ, i ); + + return std::make_tuple ( res.first, res.second, occ ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +template < class SymbolType, class RankType, class StateType > +std::pair < bool, std::set < StateType > > Run::calculateStates ( const automaton::NFTA < SymbolType, RankType, StateType > & automaton, const std::tree < std::ranked_symbol < SymbolType, RankType > > & node, std::set < unsigned > & occ, unsigned & i ) { + std::vector < std::set < StateType > > resStates; + + resStates.reserve ( ( size_t ) node.getData ( ).getRank ( ) ); + + unsigned tmp = i; + i++; + + bool sign = true; + + for ( const std::tree < std::ranked_symbol < SymbolType, RankType > > & child : node.getChildren ( ) ) { + std::pair < bool, std::set < StateType > > childStates = calculateStates ( automaton, child, occ, i ); + + if ( childStates.second.empty ( ) ) + sign = false; + + resStates.push_back ( childStates.second ); + } + + std::set < StateType > states; + + for ( const auto & transition : automaton.getTransitions ( ) ) { + if ( transition.first.first != node.getData ( ) ) + continue; + + unsigned rank = ( unsigned ) transition.first.first.getRank ( ); + unsigned j; + + for ( j = 0; j < rank; j++ ) + if ( !resStates[j].count ( transition.first.second[j] ) ) + break; + + if ( j == rank ) + states.insert ( transition.second.begin ( ), transition.second.end ( ) ); + } + + for ( const StateType & state : states ) + if ( automaton.getFinalStates ( ).count ( state ) ) occ.insert ( tmp ); + + if ( common::GlobalData::verbose ) + std::clog << states << std::endl; + + return std::make_pair ( sign, states ); +} + +template < class SymbolType, class RankType, class StateType > +std::tuple < bool, std::set < StateType >, std::set < unsigned > > Run::calculateStates ( const automaton::NFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree ) { + std::set < unsigned > occ; + unsigned i = 0; + std::pair < bool, std::set < StateType > > res = calculateStates ( automaton, tree.getContent ( ), occ, i ); + + return std::make_tuple ( res.first, res.second, occ ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +template < class SymbolType > +bool Run::canPop ( const std::deque < SymbolType > & pushdownStore, const std::vector < SymbolType > & pop ) { + unsigned popSize = pop.size ( ); + unsigned pushdownStoreSize = pushdownStore.size ( ); + + if ( pushdownStoreSize < popSize ) return false; + + for ( unsigned i = 0; i < popSize; i++ ) + if ( pop[i] != pushdownStore[pushdownStoreSize - i - 1] ) + return false; + + return true; +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +template < class SymbolType, class StateType > +std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > Run::calculateState ( const automaton::InputDrivenDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + StateType state = automaton.getInitialState ( ); + std::deque < SymbolType > pushdownStore { + automaton.getInitialSymbol ( ) + }; + unsigned i = 0; + std::set < unsigned > occ; + bool res = true; + + if ( automaton.getFinalStates ( ).count ( state ) ) + occ.insert ( i ); + + if ( common::GlobalData::verbose ) + std::clog << state << std::endl; + + for ( const SymbolType & symbol : string.getContent ( ) ) { + auto transition = automaton.getTransitions ( ).find ( std::make_pair ( state, symbol ) ); + + if ( transition == automaton.getTransitions ( ).end ( ) ) { + res = false; + break; + } + + const std::pair < std::vector < SymbolType >, std::vector < SymbolType > > & operation = automaton.getPushdownStoreOperations ( ).find ( symbol )->second; + + if ( !canPop ( pushdownStore, operation.first ) ) { + res = false; + break; + } + + for ( unsigned j = 0; j < operation.first.size ( ); j++ ) pushdownStore.pop_back ( ); + + for ( const auto & push : std::make_reverse ( operation.second ) ) pushdownStore.push_back ( push ); + + state = transition->second; + i++; + + if ( automaton.getFinalStates ( ).count ( state ) ) + occ.insert ( i ); + + if ( common::GlobalData::verbose ) + std::clog << state << std::endl; + } + + return std::make_tuple ( res, state, occ, pushdownStore ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +template < class SymbolType, class StateType > +std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > Run::calculateState ( const automaton::VisiblyPushdownDPDA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + StateType state = automaton.getInitialState ( ); + std::deque < SymbolType > pushdownStore { + automaton.getBottomOfTheStackSymbol ( ) + }; + unsigned i = 0; + std::set < unsigned > occ; + bool res = true; + + if ( automaton.getFinalStates ( ).count ( state ) ) + occ.insert ( i ); + + if ( common::GlobalData::verbose ) + std::clog << state << std::endl; + + for ( const SymbolType & symbol : string.getContent ( ) ) { + if ( automaton.getCallInputAlphabet ( ).count ( symbol ) ) { + auto transition = automaton.getCallTransitions ( ).find ( std::make_pair ( state, symbol ) ); + + if ( transition == automaton.getCallTransitions ( ).end ( ) ) { + res = false; + break; + } + + pushdownStore.push_back ( transition->second.second ); + state = transition->second.first; + } else if ( automaton.getReturnInputAlphabet ( ).count ( symbol ) ) { + auto transition = automaton.getReturnTransitions ( ).find ( std::make_tuple ( state, symbol, pushdownStore.back ( ) ) ); + + if ( transition == automaton.getReturnTransitions ( ).end ( ) ) { + res = false; + break; + } + + if ( pushdownStore.back ( ) != automaton.getBottomOfTheStackSymbol ( ) ) pushdownStore.pop_back ( ); + + state = transition->second; + } else if ( automaton.getLocalInputAlphabet ( ).count ( symbol ) ) { + auto transition = automaton.getLocalTransitions ( ).find ( std::make_pair ( state, symbol ) ); + + if ( transition == automaton.getLocalTransitions ( ).end ( ) ) { + res = false; + break; + } + + state = transition->second; + } else { + res = false; + break; + } + + i++; + + if ( automaton.getFinalStates ( ).count ( state ) ) + occ.insert ( i ); + + if ( common::GlobalData::verbose ) + std::clog << state << std::endl; + } + + return std::make_tuple ( res, state, occ, pushdownStore ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +template < class SymbolType, class EpsilonType, class StateType > +std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > Run::calculateState ( const automaton::RealTimeHeightDeterministicDPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + StateType state = automaton.getInitialState ( ); + std::deque < SymbolType > pushdownStore { + automaton.getBottomOfTheStackSymbol ( ) + }; + unsigned i = 0; + std::set < unsigned > occ; + bool res = true; + + if ( automaton.getFinalStates ( ).count ( state ) ) + occ.insert ( i ); + + if ( common::GlobalData::verbose ) + std::clog << state << std::endl; + + for ( auto symbolIter = string.getContent ( ).begin ( ); symbolIter != string.getContent ( ).end ( ); ) { + + auto callTransition = automaton.getCallTransitions ( ).find ( std::make_pair ( state, * symbolIter ) ); + + if ( callTransition != automaton.getCallTransitions ( ).end ( ) ) { + symbolIter++; + i++; + } else { + callTransition = automaton.getCallTransitions ( ).find ( std::make_pair ( state, EpsilonType ( ) ) ); + } + + if ( callTransition != automaton.getCallTransitions ( ).end ( ) ) { + pushdownStore.push_back ( callTransition->second.second ); + state = callTransition->second.first; + } else { + res = false; + } + + if ( !res ) { + auto returnTransition = automaton.getReturnTransitions ( ).find ( std::make_tuple ( state, * symbolIter, pushdownStore.back ( ) ) ); + + if ( returnTransition != automaton.getReturnTransitions ( ).end ( ) ) { + symbolIter++; + i++; + } else { + returnTransition = automaton.getReturnTransitions ( ).find ( std::make_tuple ( state, EpsilonType ( ), pushdownStore.back ( ) ) ); + } + + if ( returnTransition != automaton.getReturnTransitions ( ).end ( ) ) { + pushdownStore.pop_back ( ); + state = returnTransition->second; + } else { + res = false; + } + } + + if ( !res ) { + auto localTransition = automaton.getLocalTransitions ( ).find ( std::make_pair ( state, * symbolIter ) ); + + if ( localTransition != automaton.getLocalTransitions ( ).end ( ) ) { + symbolIter++; + i++; + } else { + localTransition = automaton.getLocalTransitions ( ).find ( std::make_pair ( state, EpsilonType ( ) ) ); + } + + if ( localTransition != automaton.getLocalTransitions ( ).end ( ) ) + state = localTransition->second; + else + res = false; + } + + if ( automaton.getFinalStates ( ).count ( state ) ) + occ.insert ( i ); + + if ( common::GlobalData::verbose ) + std::clog << state << std::endl; + + if ( res == false ) + break; + } + + return std::make_tuple ( res, state, occ, pushdownStore ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +template < class SymbolType, class EpsilonType, class StateType > +std::tuple < bool, StateType, std::set < unsigned >, std::deque < SymbolType > > Run::calculateState ( const automaton::DPDA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + StateType state = automaton.getInitialState ( ); + std::deque < SymbolType > pushdownStore { + automaton.getInitialSymbol ( ) + }; + unsigned i = 0; + std::set < unsigned > occ; + bool res = true; + + if ( automaton.getFinalStates ( ).count ( state ) ) + occ.insert ( i ); + + if ( common::GlobalData::verbose ) { + std::clog << "State : " << state << std::endl; + std::clog << "PushdownStore : " << pushdownStore << std::endl; + } + + for ( auto symbolIter = string.getContent ( ).begin ( ); symbolIter != string.getContent ( ).end ( ); ) { + auto transitions = automaton.getTransitionsFromState ( state ); + auto transition = transitions.begin ( ); + + for ( ; transition != transitions.end ( ); transition++ ) { + if ( ( std::get < 1 > ( transition->first ) != * symbolIter ) && !std::get < 1 > ( transition->first ).template is < EpsilonType > ( ) ) continue; + + if ( canPop ( pushdownStore, std::get < 2 > ( transition->first ) ) ) break; + } + + if ( transition == transitions.end ( ) ) { + res = false; + break; + } + + if ( common::GlobalData::verbose ) + std::clog << "Transition: " << * transition << std::endl; + + for ( unsigned j = 0; j < std::get < 2 > ( transition->first ).size ( ); j++ ) pushdownStore.pop_back ( ); + + for ( const auto & symbol : std::make_reverse ( transition->second.second ) ) pushdownStore.push_back ( symbol ); + + state = transition->second.first; + + if ( !std::get < 1 > ( transition->first ).template is < EpsilonType > ( ) ) { + i++; + symbolIter++; + } + + if ( automaton.getFinalStates ( ).count ( state ) ) + occ.insert ( i ); + + if ( common::GlobalData::verbose ) { + std::clog << "State: " << state << std::endl; + std::clog << "PushdownStore: " << pushdownStore << std::endl; + } + } + + return std::make_tuple ( res, state, occ, pushdownStore ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +template < class SymbolType > +struct graphStructuredStack { + graphStructuredStack ( std::shared_ptr < graphStructuredStack < SymbolType > > parent, SymbolType data ) : m_parent(parent), m_data(data) {} + std::shared_ptr < graphStructuredStack < SymbolType > > m_parent; + SymbolType m_data; +}; + +template < class SymbolType, class EpsilonType, class StateType > +std::tuple < bool, std::set < StateType >, std::set < std::vector < SymbolType > > > Run::calculateStates ( const automaton::NPDTA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + bool res = false; + unsigned i = 0; + std::set < unsigned > occurrences; + StateType state = automaton . getInitialState (); + typename std::vector<SymbolType>::const_iterator symbolIter = string . getContent () . begin (); + std::shared_ptr < graphStructuredStack < SymbolType > > stackNode = std::make_shared < graphStructuredStack < SymbolType > > ( nullptr, * symbolIter ); + std::shared_ptr < graphStructuredStack < SymbolType > > outputNode = std::make_shared < graphStructuredStack < SymbolType > > ( nullptr, * symbolIter ); + + if ( automaton . getFinalStates () . count ( state ) ) { + occurrences . insert ( i ); + } + + std::deque < std::tuple < StateType, typename std::vector<SymbolType>::const_iterator, std::shared_ptr < graphStructuredStack < SymbolType > >, std::shared_ptr < graphStructuredStack < SymbolType > > > > bftQueue; + auto configuration = std::make_tuple ( state, symbolIter, stackNode, outputNode ); + bftQueue . push_back ( configuration ); + + std::set < std::vector < SymbolType > > allOutputs; + std::set < StateType > 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 -> m_parent == NULL ) { + res = true; + std::vector < SymbolType > output; + while ( outputNode->m_parent != NULL ) { + output . push_back ( outputNode->m_data ); + outputNode = outputNode -> m_parent; + } + std::reverse ( output.begin(), output.end() ); + allOutputs . insert ( output ); + } + continue; + } + + for ( const auto & transition : automaton . getTransitionsFromState ( state ) ) { + if ( std::get<1>(transition . first) != * symbolIter && ! std::get<1>(transition . first) . template is < EpsilonType >() ) + continue; + + const auto & pop = std::get<2>(transition . first); + std::shared_ptr < graphStructuredStack < SymbolType > > stackNodeCopy = stackNode; + std::shared_ptr < graphStructuredStack < SymbolType > > outputNodeCopy = outputNode; + + unsigned j = 0; + for ( ; j < pop . size (); j ++ ) { + if ( stackNodeCopy->m_parent == NULL || stackNodeCopy->m_data != pop . at (j) ) { + break; + } + stackNodeCopy = stackNodeCopy -> m_parent; + } + if ( j == pop . size () ) { + for ( const auto & elem : std::make_reverse ( std::get<1>(transition . second ) ) ) { + stackNodeCopy = std::make_shared < graphStructuredStack < SymbolType > > ( stackNodeCopy, elem ); + } + for ( const auto & elem : std::get<2>(transition . second) ) { + outputNodeCopy = std::make_shared < graphStructuredStack < SymbolType > > ( outputNodeCopy, elem ); + } + + if ( ! std::get<1>(transition . first) . template is< EpsilonType > ( ) ) { + 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 ); + } + } + } + + return std::make_tuple ( res, states, allOutputs ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + } /* namespace run */ } /* namespace automaton */ diff --git a/alib2algo/src/automaton/run/Translate.cpp b/alib2algo/src/automaton/run/Translate.cpp index ff715de363..fb1bebc5c3 100644 --- a/alib2algo/src/automaton/run/Translate.cpp +++ b/alib2algo/src/automaton/run/Translate.cpp @@ -6,11 +6,6 @@ */ #include "Translate.h" -#include "Run.h" -#include <automaton/PDA/NPDTA.h> - -#include <deque> -#include <set> namespace automaton { @@ -24,16 +19,6 @@ std::set < string::LinearString < > > Translate::translate ( const automaton::Au return dispatch ( automaton.getData ( ), string ); } -std::set < string::LinearString < > > Translate::translate ( const automaton::NPDTA < > & automaton, const string::LinearString < > & string ) { - std::tuple < bool, std::set < label::Label >, 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 */ diff --git a/alib2algo/src/automaton/run/Translate.h b/alib2algo/src/automaton/run/Translate.h index fb4db98e17..aa3604fc30 100644 --- a/alib2algo/src/automaton/run/Translate.h +++ b/alib2algo/src/automaton/run/Translate.h @@ -15,6 +15,12 @@ #include <string/LinearString.h> #include <alphabet/Symbol.h> +#include "Run.h" +#include <automaton/PDA/NPDTA.h> + +#include <deque> +#include <set> + namespace automaton { namespace run { @@ -28,10 +34,22 @@ public: 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 ); + template < class SymbolType, class EpsilonType, class StateType > + static std::set < string::LinearString < SymbolType > > translate ( const automaton::NPDTA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ); }; +template < class SymbolType, class EpsilonType, class StateType > +std::set < string::LinearString < SymbolType > > Translate::translate ( const automaton::NPDTA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + std::tuple < bool, std::set < StateType >, std::set < std::vector < SymbolType > > > res = Run::calculateStates ( automaton, string ); + std::set < string::LinearString < SymbolType > > strings; + for ( auto iter = std::get<2>(res).begin(); iter != std::get<2>(res).end(); iter ++ ) { + string::LinearString < SymbolType > str (* iter); + strings . insert ( str ); + } + return strings; +} + } /* namespace run */ } /* namespace automaton */ -- GitLab