From 7e3f919b6bda816ea576d0e651c6c93e0a132d74 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Fri, 1 Mar 2019 11:39:40 +0100 Subject: [PATCH] template FTA to PostfixPDA --- .../convert/ToPostfixPushdownAutomaton.cpp | 89 +------------------ .../convert/ToPostfixPushdownAutomaton.h | 75 +++++++++++++++- .../automaton/convert/FTAtoPDATest.cpp | 4 +- 3 files changed, 77 insertions(+), 91 deletions(-) diff --git a/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.cpp b/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.cpp index 9bae87f9e6..1737c77998 100644 --- a/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.cpp +++ b/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.cpp @@ -6,104 +6,19 @@ */ #include "ToPostfixPushdownAutomaton.h" - -#include <exception/CommonException.h> - -#include <alphabet/BottomOfTheStackSymbol.h> -#include <alphabet/EndSymbol.h> -#include <label/InitialStateLabel.h> -#include <label/FinalStateLabel.h> - -#include <automaton/TA/DFTA.h> -#include <automaton/TA/NFTA.h> -#include <automaton/PDA/DPDA.h> -#include <automaton/PDA/NPDA.h> - #include <registration/AlgoRegistration.hpp> namespace automaton { namespace convert { -automaton::DPDA < > ToPostfixPushdownAutomaton::convert ( const automaton::DFTA < > & dfta ) { - automaton::DPDA < > automaton(label::InitialStateLabel::instance < DefaultStateType > ( ), alphabet::BottomOfTheStackSymbol::instance < DefaultSymbolType > ( )); - - for (const auto & rankedSymbol : dfta.getInputAlphabet()) { - automaton.addInputSymbol ( DefaultSymbolType ( rankedSymbol ) ); - } - automaton.addInputSymbol(alphabet::EndSymbol::instance < DefaultSymbolType > ( )); - - for (const auto & state : dfta.getStates()) { - automaton.addPushdownStoreSymbol(state); - } - - for (const auto & transition : dfta.getTransitions()) { - ext::vector<DefaultSymbolType> pop; - pop.reserve(transition.first.second.size()); - for (const auto & state : transition.first.second) { - pop.push_back(state); - } - ext::vector<DefaultSymbolType> push (1, transition.second); - automaton.addTransition(automaton.getInitialState(), DefaultSymbolType ( common::ranked_symbol < > ( transition.first.first ) ), pop, automaton.getInitialState(), push); - } - - auto finalPDAState = label::FinalStateLabel::instance < DefaultStateType > ( ); - automaton.addState(finalPDAState); - automaton.addFinalState(finalPDAState); - - for (const auto & finalState : dfta.getFinalStates()) { - ext::vector<DefaultSymbolType> pop = {alphabet::BottomOfTheStackSymbol::instance<DefaultSymbolType>(), finalState}; - ext::vector<DefaultSymbolType> push; - automaton.addTransition(automaton.getInitialState(), alphabet::EndSymbol::instance<DefaultSymbolType>(), pop, finalPDAState, push); - } - - return automaton; -} - -automaton::NPDA < > ToPostfixPushdownAutomaton::convert ( const automaton::NFTA < > & nfta ) { - automaton::NPDA < > automaton(label::InitialStateLabel::instance < DefaultStateType > ( ), alphabet::BottomOfTheStackSymbol::instance < DefaultSymbolType > ( )); - - for (const auto & rankedSymbol : nfta.getInputAlphabet()) { - automaton.addInputSymbol ( DefaultSymbolType ( rankedSymbol ) ); - } - automaton.addInputSymbol(alphabet::EndSymbol::instance < DefaultSymbolType > ( )); - - for (const auto & state : nfta.getStates()) { - automaton.addPushdownStoreSymbol(state); - } - - for (const auto & transition : nfta.getTransitions()) { - for (const auto & toState : transition.second) { - ext::vector <DefaultSymbolType> pop; - pop.reserve(transition.first.second.size()); - for (const auto & state : transition.first.second) { - pop.push_back(state); - } - ext::vector <DefaultSymbolType> push(1, toState); - automaton.addTransition(automaton.getInitialState(), DefaultSymbolType ( common::ranked_symbol < > ( transition.first.first ) ), pop, automaton.getInitialState(), push); - } - } - - auto finalPDAState = label::FinalStateLabel::instance < DefaultStateType > ( ); - automaton.addState(finalPDAState); - automaton.addFinalState(finalPDAState); - - for (const auto & finalState : nfta.getFinalStates()) { - ext::vector<DefaultSymbolType> pop = {alphabet::BottomOfTheStackSymbol::instance<DefaultSymbolType>(), finalState}; - ext::vector<DefaultSymbolType> push; - automaton.addTransition(automaton.getInitialState(), alphabet::EndSymbol::instance<DefaultSymbolType>(), pop, finalPDAState, push); - } - - return automaton; -} - -auto ToAutomatonDFTA = registration::AbstractRegister < ToPostfixPushdownAutomaton, automaton::DPDA < >, const automaton::DFTA < > & > ( ToPostfixPushdownAutomaton::convert, "dfta" ).setDocumentation ( +auto ToAutomatonDFTA = registration::AbstractRegister < ToPostfixPushdownAutomaton, automaton::DPDA < ext::variant < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < DefaultStateType, alphabet::BottomOfTheStackSymbol >, char >, const automaton::DFTA < > & > ( ToPostfixPushdownAutomaton::convert, "dfta" ).setDocumentation ( "Performs the conversion of the deterministic FTA to the deterministic PDA\n\ \n\ @param dfta Deterministic finite tree automaton to convert\n\ @return (D)PDA equivalent to original finite tree automaton reading linearized postfix tree" ); -auto ToAutomatonNFTA = registration::AbstractRegister < ToPostfixPushdownAutomaton, automaton::NPDA < >, const automaton::NFTA < > & > ( ToPostfixPushdownAutomaton::convert, "nfta" ).setDocumentation ( +auto ToAutomatonNFTA = registration::AbstractRegister < ToPostfixPushdownAutomaton, automaton::NPDA < ext::variant < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < DefaultStateType, alphabet::BottomOfTheStackSymbol >, char >, const automaton::NFTA < > & > ( ToPostfixPushdownAutomaton::convert, "nfta" ).setDocumentation ( "Performs the conversion of the deterministic FTA to the deterministic PDA\n\ \n\ @param nfta Nondeterministic finite tree automaton to convert\n\ diff --git a/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.h b/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.h index 507e5b00f7..9b4b9e73af 100644 --- a/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.h +++ b/alib2algo/src/automaton/convert/ToPostfixPushdownAutomaton.h @@ -29,6 +29,9 @@ #include <automaton/PDA/NPDA.h> #include <automaton/PDA/DPDA.h> +#include <alphabet/BottomOfTheStackSymbol.h> +#include <alphabet/EndSymbol.h> + namespace automaton { namespace convert { @@ -43,16 +46,84 @@ public: * @param dfta Deterministic finite tree automaton to convert * @return (D)PDA equivalent to original finite tree automaton reading linearized postfix tree */ - static automaton::DPDA < > convert ( const automaton::DFTA < > & dfta ); + template < class SymbolType, class RankType, class StateType > + static automaton::DPDA < ext::variant < common::ranked_symbol < SymbolType, RankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < StateType, alphabet::BottomOfTheStackSymbol >, char > convert ( const automaton::DFTA < SymbolType, RankType, StateType > & dfta ); /** * Performs the conversion of the nondeterministic FTA to the nondeterministic PDA. * @param nfta Nondeterministic finite tree automaton to convert * @return (N)PDA equivalent to original finite tree automaton reading linearized postfix tree */ - static automaton::NPDA < > convert ( const automaton::NFTA < > & nfta ); + template < class SymbolType, class RankType, class StateType > + static automaton::NPDA < ext::variant < common::ranked_symbol < SymbolType, RankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < StateType, alphabet::BottomOfTheStackSymbol >, char > convert ( const automaton::NFTA < SymbolType, RankType, StateType > & nfta ); }; +template < class SymbolType, class RankType, class StateType > +automaton::DPDA < ext::variant < common::ranked_symbol < SymbolType, RankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < StateType, alphabet::BottomOfTheStackSymbol >, char > ToPostfixPushdownAutomaton::convert ( const automaton::DFTA < SymbolType, RankType, StateType > & dfta ) { + automaton::DPDA < ext::variant < common::ranked_symbol < SymbolType, RankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < StateType, alphabet::BottomOfTheStackSymbol >, char > automaton ( 'q', alphabet::BottomOfTheStackSymbol ( ) ); + + for ( const auto & rankedSymbol : dfta.getInputAlphabet ( ) ) { + automaton.addInputSymbol ( rankedSymbol ); + } + automaton.addInputSymbol ( alphabet::EndSymbol ( ) ); + + for ( const StateType & state : dfta.getStates ( ) ) { + automaton.addPushdownStoreSymbol ( state ); + } + + for (const auto & transition : dfta.getTransitions()) { + ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > pop ( transition.first.second.begin ( ), transition.first.second.end ( ) ); + ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > push ( 1, transition.second ); + automaton.addTransition ( automaton.getInitialState ( ), transition.first.first, pop, automaton.getInitialState ( ), push ); + } + + auto finalPDAState = 'r'; + automaton.addState ( finalPDAState ); + automaton.addFinalState ( finalPDAState ); + + for ( const auto & finalState : dfta.getFinalStates ( ) ) { + ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > pop = { finalState, alphabet::BottomOfTheStackSymbol ( ) }; + ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > push; + automaton.addTransition ( automaton.getInitialState ( ), alphabet::EndSymbol ( ), pop, finalPDAState, push ); + } + + return automaton; +} + +template < class SymbolType, class RankType, class StateType > +automaton::NPDA < ext::variant < common::ranked_symbol < SymbolType, RankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < StateType, alphabet::BottomOfTheStackSymbol >, char > ToPostfixPushdownAutomaton::convert ( const automaton::NFTA < SymbolType, RankType, StateType > & nfta ) { + automaton::NPDA < ext::variant < common::ranked_symbol < SymbolType, RankType >, alphabet::EndSymbol >, DefaultEpsilonType, ext::variant < StateType, alphabet::BottomOfTheStackSymbol >, char > automaton ( 'q', alphabet::BottomOfTheStackSymbol ( ) ); + + for ( const auto & symbol : nfta.getInputAlphabet ( ) ) { + automaton.addInputSymbol ( symbol ); + } + automaton.addInputSymbol ( alphabet::EndSymbol ( ) ); + + for ( const StateType & state : nfta.getStates ( ) ) { + automaton.addPushdownStoreSymbol ( state ); + } + + for ( const auto & transition : nfta.getTransitions ( ) ) { + for ( const StateType & toState : transition.second ) { + ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > pop ( transition.first.second.begin ( ), transition.first.second.end ( ) ); + ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > push ( 1, toState ); + automaton.addTransition (automaton.getInitialState ( ), transition.first.first, pop, automaton.getInitialState ( ), push ); + } + } + + char finalPDAState = 'r'; + automaton.addState ( finalPDAState ); + automaton.addFinalState ( finalPDAState ); + + for ( const StateType & finalState : nfta.getFinalStates ( ) ) { + ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > pop = { finalState, alphabet::BottomOfTheStackSymbol ( ) }; + ext::vector < ext::variant < StateType, alphabet::BottomOfTheStackSymbol > > push; + automaton.addTransition ( automaton.getInitialState ( ), alphabet::EndSymbol ( ), pop, finalPDAState, push ); + } + + return automaton; +} + } /* namespace convert */ } /* namespace automaton */ diff --git a/alib2algo/test-src/automaton/convert/FTAtoPDATest.cpp b/alib2algo/test-src/automaton/convert/FTAtoPDATest.cpp index 5e8ca0332f..f71056d9df 100644 --- a/alib2algo/test-src/automaton/convert/FTAtoPDATest.cpp +++ b/alib2algo/test-src/automaton/convert/FTAtoPDATest.cpp @@ -41,7 +41,7 @@ TEST_CASE ( "FTAtoPDA", "[unit][algo][automaton][convert]" ) { automaton.addFinalState(DefaultStateType(3)); - automaton::DPDA < > res = automaton::convert::ToPostfixPushdownAutomaton::convert(automaton); + automaton::DPDA < ext::variant < common::ranked_symbol < object::Object, unsigned int >, alphabet::EndSymbol >, string::Epsilon < >, ext::variant < object::Object, alphabet::BottomOfTheStackSymbol >, char > res = automaton::convert::ToPostfixPushdownAutomaton::convert(automaton); CHECK(res.getStates().size() == 2); CHECK(res.getTransitions().size() == 5); CHECK(res.getFinalStates().size() == 1); @@ -72,7 +72,7 @@ TEST_CASE ( "FTAtoPDA", "[unit][algo][automaton][convert]" ) { automaton.addFinalState(DefaultStateType(3)); - automaton::NPDA < > res = automaton::convert::ToPostfixPushdownAutomaton::convert(automaton); + automaton::NPDA < ext::variant < common::ranked_symbol < object::Object, unsigned int >, alphabet::EndSymbol >, string::Epsilon < >, ext::variant < object::Object, alphabet::BottomOfTheStackSymbol >, char > res = automaton::convert::ToPostfixPushdownAutomaton::convert ( automaton ); CHECK(res.getStates().size() == 2); CHECK(res.getTransitions().size() == 5); -- GitLab