diff --git a/alib2algo/src/automaton/run/Accept.cpp b/alib2algo/src/automaton/run/Accept.cpp index bcf456b5e41eca3df11a46199e50ef5682e76112..af6d1a08d6760ac9e84448f1aefdcf088087ccc7 100644 --- a/alib2algo/src/automaton/run/Accept.cpp +++ b/alib2algo/src/automaton/run/Accept.cpp @@ -10,9 +10,11 @@ #include <exception/AlibException.h> #include <automaton/FSM/DFA.h> #include <automaton/FSM/NFA.h> -#include <automaton/PDA/DPDA.h> #include <automaton/TA/DFTA.h> #include <automaton/TA/NFTA.h> +#include <automaton/PDA/InputDrivenDPDA.h> +#include <automaton/PDA/VisiblyPushdownDPDA.h> +#include <automaton/PDA/DPDA.h> #include <deque> #include <algorithm> @@ -69,6 +71,22 @@ bool Accept::accept ( const automaton::NFTA & automaton, const tree::RankedTree auto AcceptNFTARankedTree = Accept::RegistratorWrapper < bool, automaton::NFTA, tree::RankedTree > ( Accept::getInstance ( ), Accept::accept ); +bool Accept::accept ( const automaton::InputDrivenDPDA & automaton, const string::LinearString & string ) { + std::tuple < bool, automaton::State, std::set < unsigned > > res = Run::calculateState ( automaton, string ); + + return std::get < 0 > ( res ) && automaton.getFinalStates ( ).count ( std::get < 1 > ( res ) ); +} + +auto AcceptInputDrivenDPDALinearString = Accept::RegistratorWrapper < bool, automaton::InputDrivenDPDA, string::LinearString > ( Accept::getInstance ( ), Accept::accept ); + +bool Accept::accept ( const automaton::VisiblyPushdownDPDA & automaton, const string::LinearString & string ) { + std::tuple < bool, automaton::State, std::set < unsigned > > 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::getInstance ( ), Accept::accept ); + bool Accept::accept ( const automaton::DPDA & automaton, const string::LinearString & string ) { std::tuple < bool, automaton::State, std::set < unsigned > > res = Run::calculateState ( automaton, string ); diff --git a/alib2algo/src/automaton/run/Accept.h b/alib2algo/src/automaton/run/Accept.h index d1d759b67961936ad9a7ded2eb0b0e881933ecf6..c3a787711534d7c35d4625126dd6bac90ae115b6 100644 --- a/alib2algo/src/automaton/run/Accept.h +++ b/alib2algo/src/automaton/run/Accept.h @@ -30,9 +30,11 @@ public: static bool accept ( const automaton::DFA & automaton, const string::LinearString & string ); static bool accept ( const automaton::NFA & automaton, const string::LinearString & string ); - static bool accept ( const automaton::DPDA & automaton, const string::LinearString & string ); static bool accept ( const automaton::DFTA & automaton, const tree::RankedTree & tree ); static bool accept ( const automaton::NFTA & automaton, const tree::RankedTree & tree ); + 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::DPDA & automaton, const string::LinearString & string ); public: static Accept & getInstance ( ) { diff --git a/alib2algo/src/automaton/run/Occurrences.cpp b/alib2algo/src/automaton/run/Occurrences.cpp index 49b6d8b4c9c7bf6876df2c490d2925fbe72c6176..7080c357b073b7236ab310794f5b06bf4bddda7a 100644 --- a/alib2algo/src/automaton/run/Occurrences.cpp +++ b/alib2algo/src/automaton/run/Occurrences.cpp @@ -10,8 +10,10 @@ #include <exception/AlibException.h> #include <automaton/FSM/DFA.h> #include <automaton/FSM/NFA.h> -#include <automaton/PDA/DPDA.h> #include <automaton/TA/DFTA.h> +#include <automaton/PDA/InputDrivenDPDA.h> +#include <automaton/PDA/VisiblyPushdownDPDA.h> +#include <automaton/PDA/DPDA.h> #include <deque> @@ -47,6 +49,22 @@ std::set < unsigned > Occurrences::occurrences ( const automaton::DFTA & automat auto OccurrencesDFTARankedTree = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::DFTA, tree::RankedTree > ( Occurrences::getInstance ( ), Occurrences::occurrences ); +std::set < unsigned > Occurrences::occurrences ( const automaton::InputDrivenDPDA & automaton, const string::LinearString & string ) { + std::tuple < bool, automaton::State, std::set < unsigned > > res = Run::calculateState ( automaton, string ); + + return std::get < 2 > ( res ); +} + +auto OccurrencesInputDrivenDPDALinearString = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::InputDrivenDPDA, string::LinearString > ( Occurrences::getInstance ( ), Occurrences::occurrences ); + +std::set < unsigned > Occurrences::occurrences ( const automaton::VisiblyPushdownDPDA & automaton, const string::LinearString & string ) { + std::tuple < bool, automaton::State, std::set < unsigned > > res = Run::calculateState ( automaton, string ); + + return std::get < 2 > ( res ); +} + +auto OccurrencesVisiblyPushdownDPDALinearString = Occurrences::RegistratorWrapper < std::set < unsigned >, automaton::VisiblyPushdownDPDA, string::LinearString > ( Occurrences::getInstance ( ), Occurrences::occurrences ); + std::set < unsigned > Occurrences::occurrences ( const automaton::DPDA & automaton, const string::LinearString & string ) { std::tuple < bool, automaton::State, std::set < unsigned > > res = Run::calculateState ( automaton, string ); diff --git a/alib2algo/src/automaton/run/Occurrences.h b/alib2algo/src/automaton/run/Occurrences.h index bd915abc92debe600b52c6111e741c0518290a30..5ed8a1a157fa0736f8f97229eb4af2c185c13525 100644 --- a/alib2algo/src/automaton/run/Occurrences.h +++ b/alib2algo/src/automaton/run/Occurrences.h @@ -29,8 +29,10 @@ public: static std::set < unsigned > occurrences ( const automaton::Automaton & automaton, const tree::RankedTree & string ); static std::set < unsigned > occurrences ( const automaton::DFA & automaton, const string::LinearString & string ); - static std::set < unsigned > occurrences ( const automaton::DPDA & automaton, const string::LinearString & string ); static std::set < unsigned > occurrences ( const automaton::DFTA & automaton, const tree::RankedTree & tree ); + 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::DPDA & automaton, const string::LinearString & string ); public: static Occurrences & getInstance ( ) { diff --git a/alib2algo/src/automaton/run/Result.cpp b/alib2algo/src/automaton/run/Result.cpp index bcadf3c3c7a623bdf87c604e456cdd15ab8dff45..94c77562ae74ba2d102cc1f31f764a04247ce57b 100644 --- a/alib2algo/src/automaton/run/Result.cpp +++ b/alib2algo/src/automaton/run/Result.cpp @@ -9,8 +9,10 @@ #include "Run.h" #include <exception/AlibException.h> #include <automaton/FSM/DFA.h> -#include <automaton/PDA/DPDA.h> #include <automaton/TA/DFTA.h> +#include <automaton/PDA/InputDrivenDPDA.h> +#include <automaton/PDA/VisiblyPushdownDPDA.h> +#include <automaton/PDA/DPDA.h> #include <label/LabelSetLabel.h> #include <deque> @@ -43,6 +45,26 @@ label::Label Result::result ( const automaton::DFTA & automaton, const tree::Ran auto ResultDFTARankedTree = Result::RegistratorWrapper < label::Label, automaton::DFTA, tree::RankedTree > ( Result::getInstance ( ), Result::result ); +label::Label Result::result ( const automaton::InputDrivenDPDA & automaton, const string::LinearString & string ) { + std::tuple < bool, automaton::State, std::set < unsigned > > res = Run::calculateState ( automaton, string ); + + if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ).getName ( ); + + return label::labelFrom ( "fail" ); +} + +auto ResultInputDrivenDPDALinearString = Result::RegistratorWrapper < label::Label, automaton::InputDrivenDPDA, string::LinearString > ( Result::getInstance ( ), Result::result ); + +label::Label Result::result ( const automaton::VisiblyPushdownDPDA & automaton, const string::LinearString & string ) { + std::tuple < bool, automaton::State, std::set < unsigned > > res = Run::calculateState ( automaton, string ); + + if ( std::get < 0 > ( res ) ) return std::get < 1 > ( res ).getName ( ); + + return label::labelFrom ( "fail" ); +} + +auto ResultVisiblyPushdownDPDALinearString = Result::RegistratorWrapper < label::Label, automaton::VisiblyPushdownDPDA, string::LinearString > ( Result::getInstance ( ), Result::result ); + label::Label Result::result ( const automaton::DPDA & automaton, const string::LinearString & string ) { std::tuple < bool, automaton::State, std::set < unsigned > > res = Run::calculateState ( automaton, string ); diff --git a/alib2algo/src/automaton/run/Result.h b/alib2algo/src/automaton/run/Result.h index a172ef755d89b9673d689c0bb93b9a492cecad41..d4be690eac4910bbd7bace0c334826f32caf327b 100644 --- a/alib2algo/src/automaton/run/Result.h +++ b/alib2algo/src/automaton/run/Result.h @@ -28,8 +28,10 @@ public: static label::Label result ( const automaton::Automaton & automaton, const alib::Object & object ); static label::Label result ( const automaton::DFA & automaton, const string::LinearString & string ); - static label::Label result ( const automaton::DPDA & automaton, const string::LinearString & string ); static label::Label result ( const automaton::DFTA & automaton, const tree::RankedTree & tree ); + static label::Label result ( const automaton::InputDrivenDPDA & automaton, const string::LinearString & string ); + static label::Label result ( const automaton::VisiblyPushdownDPDA & automaton, const string::LinearString & string ); + static label::Label result ( const automaton::DPDA & automaton, const string::LinearString & string ); static Result & getInstance ( ) { static Result res; diff --git a/alib2algo/src/automaton/run/Run.cpp b/alib2algo/src/automaton/run/Run.cpp index c9f4441f090347912206bb2b17d0fb7fafc345d4..7a20f97d8d0c1a193a670578984a097e5de8abb4 100644 --- a/alib2algo/src/automaton/run/Run.cpp +++ b/alib2algo/src/automaton/run/Run.cpp @@ -11,6 +11,8 @@ #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/DPDA.h> #include <deque> @@ -190,6 +192,110 @@ bool Run::canPop ( const std::deque < alphabet::Symbol > & pushdownStore, const return true; } +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +std::tuple < bool, State, std::set < unsigned > > Run::calculateState ( const automaton::InputDrivenDPDA & automaton, const string::LinearString & string ) { + automaton::State 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 ); + + 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 ( auto iter = operation.second.rbegin ( ); iter != operation.second.rend ( ); ++iter ) pushdownStore.push_back ( * iter ); + + state = transition->second; + i++; + + if ( automaton.getFinalStates ( ).count ( state ) ) + occ.insert ( i ); + } + + return std::make_tuple ( res, state, occ ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +std::tuple < bool, State, std::set < unsigned > > Run::calculateState ( const automaton::VisiblyPushdownDPDA & automaton, const string::LinearString & string ) { + automaton::State 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 ); + + 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 ); + } + + return std::make_tuple ( res, state, occ ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + std::tuple < bool, State, std::set < unsigned > > Run::calculateState ( const automaton::DPDA & automaton, const string::LinearString & string ) { automaton::State state = automaton.getInitialState ( ); std::deque < alphabet::Symbol > pushdownStore { @@ -197,7 +303,7 @@ std::tuple < bool, State, std::set < unsigned > > Run::calculateState ( const au }; unsigned i = 0; std::set < unsigned > occ; - bool sign = true; + bool res = true; if ( automaton.getFinalStates ( ).count ( state ) ) occ.insert ( i ); @@ -215,13 +321,13 @@ std::tuple < bool, State, std::set < unsigned > > Run::calculateState ( const au } if ( transition == transitions.end ( ) ) { - sign = false; + res = false; break; } for ( unsigned j = 0; j < std::get < 2 > ( transition->first ).size ( ); j++ ) pushdownStore.pop_back ( ); - for ( const alphabet::Symbol & push : transition->second.second ) pushdownStore.push_back ( push ); + for ( auto iter = transition->second.second.rbegin ( ); iter != transition->second.second.rend ( ); ++iter ) pushdownStore.push_back ( * iter ); state = transition->second.first; i++; @@ -230,7 +336,7 @@ std::tuple < bool, State, std::set < unsigned > > Run::calculateState ( const au occ.insert ( i ); } - return std::make_tuple ( sign, state, occ ); + return std::make_tuple ( res, state, occ ); } // ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/alib2algo/src/automaton/run/Run.h b/alib2algo/src/automaton/run/Run.h index f1ce7047106ff8f0b2f168ba9796e5b22034b907..8431858b71f9379cbf474217c9310be8b3d5ca9a 100644 --- a/alib2algo/src/automaton/run/Run.h +++ b/alib2algo/src/automaton/run/Run.h @@ -27,6 +27,8 @@ public: static std::tuple < bool, std::set < State >, std::set < unsigned > > calculateStates ( const automaton::NFA & automaton, const string::LinearString & string ); static std::tuple < bool, State, std::set < unsigned > > calculateState ( const automaton::DFTA & automaton, const tree::RankedTree & tree ); static std::tuple < bool, std::set < State >, std::set < unsigned > > calculateStates ( const automaton::NFTA & automaton, const tree::RankedTree & tree ); + static std::tuple < bool, State, std::set < unsigned > > calculateState ( const automaton::InputDrivenDPDA & automaton, const string::LinearString & string ); + static std::tuple < bool, State, std::set < unsigned > > calculateState ( const automaton::VisiblyPushdownDPDA & automaton, const string::LinearString & string ); static std::tuple < bool, State, std::set < unsigned > > calculateState ( const automaton::DPDA & automaton, const string::LinearString & string ); }; diff --git a/tests.aarbology.sh b/tests.aarbology.sh index 62a646a208ca57f426568fa76534b6079adf6ecc..3ee324879b1822d52a3bcdf7a2814e8d3b0b8a70 100755 --- a/tests.aarbology.sh +++ b/tests.aarbology.sh @@ -215,4 +215,5 @@ runTestSubtree "Exact Subtree Automaton (Tree)" "./arun2 -t occurrences -a <(./a runTestPattern "Exact Boyer Moore Horspool (Pattern PrefixRankedBar)" "./aarbology2 -a boyerMooreHorspool -s <( ./acast2 -t PrefixRankedBarTree -i \"\$SUBJECT_FILE\" ) -p <( ./acast2 -t PrefixRankedBarPattern -i <(./alphabetManip2 -o add -i \"\$PATTERN_FILE\" -a <(./alphabetManip2 -o get -i \"\$SUBJECT_FILE\"))) | ./astat2 -p size --set" runTestPattern "Exact Knuth Morris Pratt (Pattern PrefixRankedBar)" "./aarbology2 -a knuthMorrisPratt -s <( ./acast2 -t PrefixRankedBarTree -i \"\$SUBJECT_FILE\" ) -p <( ./acast2 -t PrefixRankedBarPattern -i \"\$PATTERN_FILE\" ) | ./astat2 -p size --set" runTestPattern "Exact Knuth Morris Pratt (Pattern PrefixBar)" "./aarbology2 -a knuthMorrisPratt -s <( ./acast2 -t PrefixRankedTree -i \"\$SUBJECT_FILE\" ) -p <( ./acast2 -t PrefixRankedPattern -i \"\$PATTERN_FILE\" ) | ./astat2 -p size --set" -runTestPattern "Exact Pattern Automaton (Pattern Tree)" "./arun2 -t occurrences -a <(./aarbology2 -a exactPatternMatchingAutomaton -p <(./alphabetManip2 -o add -i \"\$PATTERN_FILE\" -a <(./alphabetManip2 -o get -i \"\$SUBJECT_FILE\")) | ./adeterminize2) -i \"\$SUBJECT_FILE\" | ./astat2 -p size --set" +runTestPattern "Exact Pattern Matching Automaton (Pattern Tree)" "./arun2 -t occurrences -a <(./aarbology2 -a exactPatternMatchingAutomaton -p <(./alphabetManip2 -o add -i \"\$PATTERN_FILE\" -a <(./alphabetManip2 -o get -i \"\$SUBJECT_FILE\")) | ./adeterminize2) -i \"\$SUBJECT_FILE\" | ./astat2 -p size --set" +runTestPattern "Exact Pattern Matching Automaton (PrefixRankedBar)" "./aarbology2 -a exactPatternMatchingAutomaton -p <(./acast2 -t PrefixRankedBarPattern -i <(./alphabetManip2 -o add -i \"\$PATTERN_FILE\" -a <( ./alphabetManip2 -o get -i \"\$SUBJECT_FILE\" ) ) ) | ./adeterminize2 | ./arun2 -t occurrences -a - -i <( ./acast2 -t PrefixRankedBarTree -i \"\$SUBJECT_FILE\" | ./acast2 -t LinearString ) | ./astat2 -p size --set"