From 10de8dd25273717be996a58533e1860d778d7b67 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Wed, 25 Apr 2018 09:05:12 +0200 Subject: [PATCH] implement run of Epsilon NFA --- alib2algo/src/automaton/run/Accept.cpp | 1 + alib2algo/src/automaton/run/Accept.h | 11 +++++ alib2algo/src/automaton/run/Occurrences.h | 1 - alib2algo/src/automaton/run/Run.h | 55 +++++++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/alib2algo/src/automaton/run/Accept.cpp b/alib2algo/src/automaton/run/Accept.cpp index b1bd895e5e..725e85f854 100644 --- a/alib2algo/src/automaton/run/Accept.cpp +++ b/alib2algo/src/automaton/run/Accept.cpp @@ -14,6 +14,7 @@ namespace run { auto AcceptDFALinearString = registration::AbstractRegister < Accept, bool, const automaton::DFA < > &, const string::LinearString < > & > ( Accept::accept ); auto AcceptNFALinearString = registration::AbstractRegister < Accept, bool, const automaton::NFA < > &, const string::LinearString < > & > ( Accept::accept ); +auto AcceptEpsilonNFALinearString = registration::AbstractRegister < Accept, bool, const automaton::EpsilonNFA < > &, const string::LinearString < > & > ( Accept::accept ); auto AcceptDFTARankedTree = registration::AbstractRegister < Accept, bool, const automaton::DFTA < > &, const tree::RankedTree < > & > ( Accept::accept ); auto AcceptNFTARankedTree = registration::AbstractRegister < Accept, bool, const automaton::NFTA < > &, const tree::RankedTree < > & > ( Accept::accept ); auto AcceptInputDrivenDPDALinearString = registration::AbstractRegister < Accept, bool, const automaton::InputDrivenDPDA < > &, const string::LinearString < > & > ( Accept::accept ); diff --git a/alib2algo/src/automaton/run/Accept.h b/alib2algo/src/automaton/run/Accept.h index c4f2a150a3..7651184918 100644 --- a/alib2algo/src/automaton/run/Accept.h +++ b/alib2algo/src/automaton/run/Accept.h @@ -40,6 +40,8 @@ public: 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 EpsilonType, class StateType > + static bool accept ( const automaton::EpsilonNFA < SymbolType, EpsilonType, 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 > @@ -73,6 +75,15 @@ bool Accept::accept ( const automaton::NFA < SymbolType, StateType > & automaton } ); } +template < class SymbolType, class EpsilonType, class StateType > +bool Accept::accept ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + ext::tuple < bool, ext::set < StateType >, ext::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 ) { ext::tuple < bool, StateType, ext::set < unsigned > > res = Run::calculateState ( automaton, tree ); diff --git a/alib2algo/src/automaton/run/Occurrences.h b/alib2algo/src/automaton/run/Occurrences.h index 5a3b7ad42c..29243e3579 100644 --- a/alib2algo/src/automaton/run/Occurrences.h +++ b/alib2algo/src/automaton/run/Occurrences.h @@ -13,7 +13,6 @@ #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> diff --git a/alib2algo/src/automaton/run/Run.h b/alib2algo/src/automaton/run/Run.h index 9ecd196378..d292f1a03b 100644 --- a/alib2algo/src/automaton/run/Run.h +++ b/alib2algo/src/automaton/run/Run.h @@ -13,6 +13,7 @@ #include <automaton/FSM/DFA.h> #include <automaton/FSM/NFA.h> +#include <automaton/FSM/EpsilonNFA.h> #include <automaton/TA/DFTA.h> #include <automaton/TA/NFTA.h> #include <automaton/PDA/InputDrivenDPDA.h> @@ -28,6 +29,8 @@ #include <alib/algorithm> #include <alib/iterator> +#include <automaton/properties/EpsilonClosure.h> + namespace automaton { namespace run { @@ -45,6 +48,8 @@ public: static ext::tuple < bool, StateType, ext::set < unsigned > > calculateState ( const automaton::DFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); template < class SymbolType, class StateType > static ext::tuple < bool, ext::set < StateType >, ext::set < unsigned > > calculateStates ( const automaton::NFA < SymbolType, StateType > & automaton, const string::LinearString < SymbolType > & string ); + template < class SymbolType, class EpsilonType, class StateType > + static ext::tuple < bool, ext::set < StateType >, ext::set < unsigned > > calculateStates ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ); template < class SymbolType, class RankType, class StateType > static ext::tuple < bool, StateType, ext::set < unsigned > > calculateState ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const tree::RankedTree < SymbolType, RankType > & tree ); template < class SymbolType, class RankType, class StateType > @@ -142,6 +147,56 @@ ext::tuple < bool, ext::set < StateType >, ext::set < unsigned > > Run::calculat // ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +template < class SymbolType, class EpsilonType, class StateType > +ext::tuple < bool, ext::set < StateType >, ext::set < unsigned > > Run::calculateStates ( const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton, const string::LinearString < SymbolType > & string ) { + bool res = true; + unsigned i = 0; + ext::set < unsigned > occurrences; + ext::set < StateType > states { + automaton.getInitialState ( ) + }; + + for ( const StateType & state : states ) + if ( automaton.getFinalStates ( ).count ( state ) ) + occurrences.insert ( i ); + + if ( common::GlobalData::verbose ) + common::Streams::log << states << std::endl; + + for ( const SymbolType & symbol : string.getContent ( ) ) { + ext::set < StateType > next; + + for ( const StateType & state : states ) { + auto transitions = automaton.getTransitions ( ).find ( ext::make_pair ( state, ext::variant < EpsilonType, SymbolType > ( symbol ) ) ); + + if ( transitions == automaton.getTransitions ( ).end ( ) ) continue; + + next.insert ( transitions->second.begin ( ), transitions->second.end ( ) ); + } + + ext::set < StateType > epsilonNext; + + for ( const StateType & state : next ) { + const ext::set < StateType > closure = automaton::properties::EpsilonClosure::epsilonClosure ( automaton, state ); + epsilonNext.insert ( closure.begin ( ), closure.end ( ) ); + } + + i++; + states = epsilonNext; + + for ( const StateType & state : states ) + if ( automaton.getFinalStates ( ).count ( state ) ) + occurrences.insert ( i ); + + if ( common::GlobalData::verbose ) + common::Streams::log << states << std::endl; + } + + return ext::make_tuple ( res, states, occurrences ); +} + +// ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + template < class SymbolType, class RankType, class StateType > ext::pair < bool, StateType > Run::calculateState ( const automaton::DFTA < SymbolType, RankType, StateType > & automaton, const ext::tree < common::ranked_symbol < SymbolType, RankType > > & node, ext::set < unsigned > & occ, unsigned & i ) { ext::vector < StateType > states; -- GitLab