From 5b72cad48bea97bdca82a138cbb00ab390d7d872 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Wed, 5 Apr 2017 09:32:06 +0200 Subject: [PATCH] add Transitions in pushdown automata --- alib2data/src/automaton/PDA/InputDrivenNPDA.h | 27 ++++ alib2data/src/automaton/PDA/NPDA.h | 50 +++++++ alib2data/src/automaton/PDA/NPDTA.h | 54 ++++++++ .../PDA/RealTimeHeightDeterministicNPDA.h | 122 ++++++++++++++++++ alib2data/src/automaton/PDA/SinglePopNPDA.h | 48 +++++++ .../src/automaton/PDA/VisiblyPushdownNPDA.h | 80 ++++++++++++ 6 files changed, 381 insertions(+) diff --git a/alib2data/src/automaton/PDA/InputDrivenNPDA.h b/alib2data/src/automaton/PDA/InputDrivenNPDA.h index 4dab6203a5..03646f62aa 100644 --- a/alib2data/src/automaton/PDA/InputDrivenNPDA.h +++ b/alib2data/src/automaton/PDA/InputDrivenNPDA.h @@ -158,6 +158,15 @@ public: */ bool addTransition ( StateType current, InputSymbolType input, StateType next ); + /** + * Adds transition defined by parameters to the automaton. + * @param current current state + * @param input input symbol + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addTransitions ( StateType current, InputSymbolType input, std::set < StateType > next ); + /** * Removes transition from the automaton. * @param transition transition to remove @@ -304,6 +313,24 @@ bool InputDrivenNPDA < InputSymbolType, PushdownStoreSymbolType, StateType >::ad return transitions[std::move(key)].insert(std::move(to)).second; } +template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > +void InputDrivenNPDA < InputSymbolType, PushdownStoreSymbolType, StateType >::addTransitions ( StateType from, InputSymbolType input, std::set < StateType > to) { + if (! getStates().count(from)) + throw AutomatonException("State \"" + std::to_string ( from ) + "\" doesn't exist."); + + if (! getInputAlphabet().count(input)) + throw AutomatonException("Input symbol \"" + std::to_string ( input ) + "\" doesn't exist."); + + if (! getPushdownStoreOperations().count(input)) + throw AutomatonException("Input symbol \"" + std::to_string ( input ) + "\" doesn't exist."); + + if ( !std::includes ( getStates ( ).begin ( ), getStates ( ).end ( ), to.begin ( ), to.end ( ) ) ) + throw AutomatonException ( "Some target states don't exist." ); + + std::pair<StateType, InputSymbolType> key = std::make_pair(std::move(from), std::move(input)); + transitions [ std::move ( key ) ].insert ( std::make_moveable_set ( to ).begin ( ), std::make_moveable_set ( to ).end ( ) ); +} + template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > bool InputDrivenNPDA < InputSymbolType, PushdownStoreSymbolType, StateType >::removeTransition(const StateType& from, const InputSymbolType& input, const StateType& to) { std::pair<StateType, InputSymbolType> key = std::make_pair(from, input); diff --git a/alib2data/src/automaton/PDA/NPDA.h b/alib2data/src/automaton/PDA/NPDA.h index 590f0a2a65..31e951592d 100644 --- a/alib2data/src/automaton/PDA/NPDA.h +++ b/alib2data/src/automaton/PDA/NPDA.h @@ -150,6 +150,18 @@ public: bool addTransition ( StateType from, std::vector < PushdownStoreSymbolType > pop, StateType to, std::vector < PushdownStoreSymbolType > push ); + /** + * Adds transition to the NPDA. + * @param transition transition to add + * @throws AutomatonException when some part of the transition is not present + * in the NPDA (state, input symbol, stack symbol) or when transition already exists + */ + void addTransitions ( StateType from, std::variant < EpsilonType, InputSymbolType > input, std::vector < PushdownStoreSymbolType > pop, std::set < std::pair < StateType, std::vector < PushdownStoreSymbolType > > > targets ); + + void addTransitions ( StateType from, InputSymbolType input, std::vector < PushdownStoreSymbolType > pop, std::set < std::pair < StateType, std::vector < PushdownStoreSymbolType > > > targets ); + + void addTransitions ( StateType from, std::vector < PushdownStoreSymbolType > pop, std::set < std::pair < StateType, std::vector < PushdownStoreSymbolType > > > targets ); + /** * Removes the transition from the NPDA. * @param transition transition to remove @@ -248,6 +260,44 @@ bool NPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >:: return addTransition(std::move(from), std::move(inputVariant), std::move(pop), std::move(to), std::move(push)); } +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void NPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addTransitions ( StateType from, std::variant < EpsilonType, InputSymbolType > input, std::vector < PushdownStoreSymbolType > pop, std::set < std::pair < StateType, std::vector < PushdownStoreSymbolType > > > targets ) { + if (! getStates().count(from)) + throw AutomatonException("State \"" + std::to_string ( from ) + "\" doesn't exist."); + + if (input.template is<InputSymbolType>() && ! getInputAlphabet().count(input.template get<InputSymbolType>())) + throw AutomatonException("Input symbol \"" + std::to_string ( input.template get<InputSymbolType>() ) + "\" doesn't exist."); + + for(const PushdownStoreSymbolType& popSymbol : pop) + if (! getPushdownStoreAlphabet().count(popSymbol)) + throw AutomatonException("Pushdown store symbol \"" + std::to_string ( popSymbol ) + "\" doesn't exist."); + + for ( const std::pair < StateType, std::vector < PushdownStoreSymbolType > > & target : targets ) { + if (! getStates().count ( target.first ) ) + throw AutomatonException("State \"" + std::to_string ( target.first ) + "\" doesn't exist."); + + for ( const PushdownStoreSymbolType& pushSymbol : target.second ) + if (! getPushdownStoreAlphabet().count(pushSymbol)) + throw AutomatonException("Pushdown store symbol \"" + std::to_string ( pushSymbol ) + "\" doesn't exist."); + } + + std::tuple<StateType, std::variant < EpsilonType, InputSymbolType >, std::vector<PushdownStoreSymbolType> > key(std::move(from), std::move(input), std::move(pop)); + + transitions [ std::move ( key ) ].insert ( std::make_moveable_set ( targets ).begin ( ), std::make_moveable_set ( targets ).end ( ) ); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void NPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addTransitions ( StateType from, InputSymbolType input, std::vector < PushdownStoreSymbolType > pop, std::set < std::pair < StateType, std::vector < PushdownStoreSymbolType > > > targets ) { + std::variant < EpsilonType, InputSymbolType > inputVariant(std::move(input)); + addTransitions ( std::move ( from ), std::move ( inputVariant ), std::move ( pop ), std::move ( targets ) ); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void NPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addTransitions ( StateType from, std::vector < PushdownStoreSymbolType > pop, std::set < std::pair < StateType, std::vector < PushdownStoreSymbolType > > > targets ) { + auto inputVariant = std::variant < EpsilonType, InputSymbolType >::template from < EpsilonType > ( ); + addTransitions ( std::move ( from ), std::move ( inputVariant ), std::move ( pop ), std::move ( targets ) ); +} + template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > bool NPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::removeTransition(const StateType& from, const std::variant < EpsilonType, InputSymbolType > & input, const std::vector<PushdownStoreSymbolType>& pop, const StateType& to, const std::vector<PushdownStoreSymbolType>& push) { std::tuple<StateType, std::variant < EpsilonType, InputSymbolType >, std::vector<PushdownStoreSymbolType> > key(from, input, pop); diff --git a/alib2data/src/automaton/PDA/NPDTA.h b/alib2data/src/automaton/PDA/NPDTA.h index b37f95ad80..1b134ac3f5 100644 --- a/alib2data/src/automaton/PDA/NPDTA.h +++ b/alib2data/src/automaton/PDA/NPDTA.h @@ -172,6 +172,18 @@ public: bool addTransition ( StateType from, std::vector < PushdownStoreSymbolType > pop, StateType to, std::vector < PushdownStoreSymbolType > push, std::vector < OutputSymbolType > output ); + /** + * Adds transition to the NPDTA. + * @param transition transition to add + * @throws AutomatonException when some part of the transition is not present + * in the NPDTA (state, input symbol, stack symbol, output symbol) or when transition already exists + */ + void addTransitions ( StateType from, std::variant < EpsilonType, InputSymbolType > input, std::vector < PushdownStoreSymbolType > pop, std::set < std::tuple < StateType, std::vector < PushdownStoreSymbolType >, std::vector < OutputSymbolType > > > targets ); + + void addTransitions ( StateType from, InputSymbolType input, std::vector < PushdownStoreSymbolType > pop, std::set < std::tuple < StateType, std::vector < PushdownStoreSymbolType >, std::vector < OutputSymbolType > > > targets ); + + void addTransitions ( StateType from, std::vector < PushdownStoreSymbolType > pop, std::set < std::tuple < StateType, std::vector < PushdownStoreSymbolType >, std::vector < OutputSymbolType > > > targets ); + /** * Removes the transition from the NPDTA. * @param transition transition to remove @@ -285,6 +297,48 @@ bool NPDTA < InputSymbolType, OutputSymbolType, EpsilonType, PushdownStoreSymbol return addTransition(std::move(from), std::move(inputVariant), std::move(pop), std::move(to), std::move(push), std::move(output)); } +template < class InputSymbolType, class OutputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void NPDTA < InputSymbolType, OutputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addTransitions ( StateType from, std::variant < EpsilonType, InputSymbolType > input, std::vector<PushdownStoreSymbolType> pop, std::set < std::tuple < StateType, std::vector < PushdownStoreSymbolType >, std::vector < OutputSymbolType > > > targets ) { + if ( ! getStates ( ).count ( from ) ) + throw AutomatonException ( "State \"" + std::to_string ( from ) + "\" doesn't exist." ); + + if ( input.template is < InputSymbolType > ( ) && ! getInputAlphabet ( ).count ( input.template get < InputSymbolType > ( ) ) ) + throw AutomatonException ( "Input symbol \"" + std::to_string ( input.template get < InputSymbolType >() ) + "\" doesn't exist." ); + + for ( const PushdownStoreSymbolType & popSymbol : pop) + if (!getPushdownStoreAlphabet ( ).count ( popSymbol ) ) + throw AutomatonException ( "Pushdown store symbol \"" + std::to_string ( popSymbol ) + "\" doesn't exist." ); + + for ( const std::tuple < StateType, std::vector < PushdownStoreSymbolType >, std::vector < OutputSymbolType > > & target : targets ) { + if ( ! getStates ( ).count ( std::get < 0 > ( target ) ) ) + throw AutomatonException ( "State \"" + std::to_string ( std::get < 0 > ( target ) ) + "\" doesn't exist." ); + + for ( const PushdownStoreSymbolType& pushSymbol : std::get < 1 > ( target ) ) + if ( ! getPushdownStoreAlphabet ( ).count ( pushSymbol ) ) + throw AutomatonException ( "Pushdown store symbol \"" + std::to_string ( pushSymbol ) + "\" doesn't exist." ); + + for ( const OutputSymbolType& outputSymbol : std::get < 2 > ( target ) ) + if ( ! getOutputAlphabet ( ).count ( outputSymbol ) ) + throw AutomatonException ( "Output symbol \"" + std::to_string ( outputSymbol ) + "\" doesn't exist." ); + } + + std::tuple < StateType, std::variant < EpsilonType, InputSymbolType >, std::vector < PushdownStoreSymbolType > > key ( std::move ( from ), std::move ( input ), std::move ( pop ) ); + + transitions [ std::move ( key ) ].insert ( std::make_moveable_set ( targets ).begin ( ), std::make_moveable_set ( targets ).end ( ) ); +} + +template < class InputSymbolType, class OutputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void NPDTA < InputSymbolType, OutputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addTransitions ( StateType from, InputSymbolType input, std::vector<PushdownStoreSymbolType> pop, std::set < std::tuple < StateType, std::vector < PushdownStoreSymbolType >, std::vector < OutputSymbolType > > > targets ) { + std::variant < EpsilonType, InputSymbolType > inputVariant ( std::move ( input ) ); + addTransition ( std::move ( from ), std::move ( inputVariant ), std::move ( pop ), std::move ( targets ) ); +} + +template < class InputSymbolType, class OutputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void NPDTA < InputSymbolType, OutputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addTransitions ( StateType from, std::vector<PushdownStoreSymbolType> pop, std::set < std::tuple < StateType, std::vector < PushdownStoreSymbolType >, std::vector < OutputSymbolType > > > targets ) { + auto inputVariant = std::variant < EpsilonType, InputSymbolType >::template from < EpsilonType > ( ); + addTransition ( std::move ( from ), std::move ( inputVariant ), std::move ( pop ), std::move ( targets ) ); +} + template < class InputSymbolType, class OutputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > bool NPDTA < InputSymbolType, OutputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::removeTransition(const StateType& from, const std::variant < EpsilonType, InputSymbolType >& input, const std::vector < PushdownStoreSymbolType > & pop, const StateType& to, const std::vector<PushdownStoreSymbolType>& push, const std::vector < OutputSymbolType > & output) { std::tuple<StateType, std::variant < EpsilonType, InputSymbolType >, std::vector<PushdownStoreSymbolType> > key(from, input, pop); diff --git a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h index 7bdd3441a8..ad866c4fe4 100644 --- a/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h +++ b/alib2data/src/automaton/PDA/RealTimeHeightDeterministicNPDA.h @@ -181,6 +181,39 @@ public: bool addLocalTransition ( StateType current, StateType next ); bool addLocalTransition ( StateType current, InputSymbolType input, StateType next ); + /** + * Adds call transition defined by parameters to the automaton. + * @param current current state + * @param input input symbol + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addCallTransitions ( StateType current, std::variant < EpsilonType, InputSymbolType > input, std::set < std::pair < StateType, PushdownStoreSymbolType > > targets ); + void addCallTransitions ( StateType current, std::set < std::pair < StateType, PushdownStoreSymbolType > > targets ); + void addCallTransitions ( StateType current, InputSymbolType input, std::set < std::pair < StateType, PushdownStoreSymbolType > > targets ); + + /** + * Adds return transition defined by parameters to the automaton. + * @param current current state + * @param input input symbol + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addReturnTransitions ( StateType current, std::variant < EpsilonType, InputSymbolType > input, PushdownStoreSymbolType pop, std::set < StateType > next ); + void addReturnTransitions ( StateType current, PushdownStoreSymbolType pop, std::set < StateType > next ); + void addReturnTransitions ( StateType current, InputSymbolType input, PushdownStoreSymbolType pop, std::set < StateType > next ); + + /** + * Adds local transition defined by parameters to the automaton. + * @param current current state + * @param input input symbol + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addLocalTransitions ( StateType current, std::variant < EpsilonType, InputSymbolType > input, std::set < StateType > next ); + void addLocalTransitions ( StateType current, std::set < StateType > next ); + void addLocalTransitions ( StateType current, InputSymbolType input, std::set < StateType > next ); + /** * Removes call transition from the automaton. * @param transition transition to remove @@ -361,6 +394,95 @@ bool RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownSto return addLocalTransition(std::move(from), std::move(inputVariant), std::move(to)); } +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addCallTransitions(StateType from, std::variant < EpsilonType, InputSymbolType > input, std::set < std::pair < StateType, PushdownStoreSymbolType > > targets ) { + if (! getStates().count(from)) + throw AutomatonException("State \"" + std::to_string ( from ) + "\" doesn't exist."); + + if (input.template is < InputSymbolType >() && ! getInputAlphabet().count(input.template get < InputSymbolType >())) + throw AutomatonException("Input symbol \"" + std::to_string ( input.template get < InputSymbolType >() ) + "\" doesn't exist."); + + for ( const std::pair < StateType, PushdownStoreSymbolType > & target : targets ) { + if ( ! getStates().count ( target.first ) ) + throw AutomatonException("State \"" + std::to_string ( target.first ) + "\" doesn't exist."); + + if ( ! getPushdownStoreAlphabet().count ( target.second ) ) + throw AutomatonException("Pushdown store symbol \"" + std::to_string ( target.second ) + "\" doesn't exist."); + } + + std::pair < StateType, std::variant < EpsilonType, InputSymbolType > > key ( std::move ( from ), std::move ( input ) ); + callTransitions [ std::move ( key ) ].insert ( std::make_moveable_set ( targets ).begin ( ), std::make_moveable_set ( targets ).end ( ) ); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addCallTransitions(StateType from, std::set < std::pair < StateType, PushdownStoreSymbolType > > targets ) { + auto inputVariant = std::variant < EpsilonType, InputSymbolType >::template from < EpsilonType > ( ); + addCallTransitions(std::move(from), std::move(inputVariant), std::move ( targets ) ); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addCallTransitions(StateType from, InputSymbolType input, std::set < std::pair < StateType, PushdownStoreSymbolType > > targets ) { + std::variant < EpsilonType, InputSymbolType > inputVariant(input); + addCallTransitions(std::move(from), std::move(inputVariant), std::move ( targets ) ); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addReturnTransitions(StateType from, std::variant < EpsilonType, InputSymbolType > input, PushdownStoreSymbolType pop, std::set < StateType > to) { + if (! getStates().count(from)) + throw AutomatonException("State \"" + std::to_string ( from ) + "\" doesn't exist."); + + if (input.template is < InputSymbolType >() && !getInputAlphabet().count(input.template get < InputSymbolType >())) + throw AutomatonException("Input symbol \"" + std::to_string ( input.template get < InputSymbolType >() ) + "\" doesn't exist."); + + if ( !std::includes ( getStates ( ).begin ( ), getStates ( ).end ( ), to.begin ( ), to.end ( ) ) ) + throw AutomatonException ( "Some target states don't exist." ); + + if ( ! getPushdownStoreAlphabet().count ( pop ) ) + throw AutomatonException("Pushdown store symbol \"" + std::to_string ( pop ) + "\" doesn't exist."); + + std::tuple<StateType, std::variant < EpsilonType, InputSymbolType >, PushdownStoreSymbolType> key(std::move(from), std::move(input), std::move(pop)); + returnTransitions[std::move(key)].insert ( std::make_moveable_set ( to ).begin ( ), std::make_moveable_set ( to ).end ( ) ); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addReturnTransitions(StateType from, PushdownStoreSymbolType pop, std::set < StateType > to) { + auto inputVariant = std::variant < EpsilonType, InputSymbolType >::template from < EpsilonType > ( ); + addReturnTransitions(std::move(from), std::move(inputVariant), std::move(pop), std::move(to)); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addReturnTransitions(StateType from, InputSymbolType input, PushdownStoreSymbolType pop, std::set < StateType > to) { + std::variant < EpsilonType, InputSymbolType > inputVariant(std::move(input)); + addReturnTransitions(std::move(from), std::move(inputVariant), std::move(pop), std::move(to)); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addLocalTransitions(StateType from, std::variant < EpsilonType, InputSymbolType > input, std::set < StateType > to) { + if (! getStates().count(from)) + throw AutomatonException("State \"" + std::to_string ( from ) + "\" doesn't exist."); + + if (input.template is < InputSymbolType >() && ! getInputAlphabet().count(input.template get < InputSymbolType >())) + throw AutomatonException("Input symbol \"" + std::to_string ( input.template get < InputSymbolType >() ) + "\" doesn't exist."); + + if ( !std::includes ( getStates ( ).begin ( ), getStates ( ).end ( ), to.begin ( ), to.end ( ) ) ) + throw AutomatonException ( "Some target states don't exist." ); + + std::pair<StateType, std::variant < EpsilonType, InputSymbolType >> key(std::move(from), std::move(input)); + localTransitions[std::move(key)].insert ( std::make_moveable_set ( to ).begin ( ), std::make_moveable_set ( to ).end ( ) ); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addLocalTransitions(StateType from, std::set < StateType > to) { + auto inputVariant = std::variant < EpsilonType, InputSymbolType >::template from < EpsilonType > ( ); + addLocalTransitions(std::move(from), std::move(inputVariant), std::move(to)); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addLocalTransitions(StateType from, InputSymbolType input, std::set < StateType > to) { + std::variant < EpsilonType, InputSymbolType > inputVariant(std::move(input)); + addLocalTransitions(std::move(from), std::move(inputVariant), std::move(to)); +} + template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > bool RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::removeCallTransition(const StateType& from, const std::variant < EpsilonType, InputSymbolType >& input, const StateType& to, const PushdownStoreSymbolType& push) { std::pair<StateType, std::variant < EpsilonType, InputSymbolType >> key(from, input); diff --git a/alib2data/src/automaton/PDA/SinglePopNPDA.h b/alib2data/src/automaton/PDA/SinglePopNPDA.h index 5602b5d998..396de82830 100644 --- a/alib2data/src/automaton/PDA/SinglePopNPDA.h +++ b/alib2data/src/automaton/PDA/SinglePopNPDA.h @@ -150,6 +150,18 @@ public: bool addTransition ( StateType from, PushdownStoreSymbolType pop, StateType to, std::vector < PushdownStoreSymbolType > push ); + /** + * Adds transition to the SinglePopNPDA. + * @param transition transition to add + * @throws AutomatonException when some part of the transition is not present + * in the SinglePopNPDA (state, input symbol, stack symbol) or when transition already exists + */ + void addTransitions ( StateType from, std::variant < EpsilonType, InputSymbolType > input, PushdownStoreSymbolType pop, std::set < std::pair < StateType, std::vector < PushdownStoreSymbolType > > > push ); + + void addTransitions ( StateType from, InputSymbolType input, PushdownStoreSymbolType pop, std::set < std::pair < StateType, std::vector < PushdownStoreSymbolType > > > push ); + + void addTransitions ( StateType from, PushdownStoreSymbolType pop, std::set < std::pair < StateType, std::vector < PushdownStoreSymbolType > > > push ); + /** * Removes the transition from the SinglePopNPDA. * @param transition transition to remove @@ -253,6 +265,42 @@ bool SinglePopNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, Stat return addTransition(std::move(from), std::move(inputVariant), std::move(pop), std::move(to), std::move(push)); } +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void SinglePopNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addTransitions(StateType from, std::variant < EpsilonType, InputSymbolType > input, PushdownStoreSymbolType pop, std::set < std::pair < StateType, std::vector < PushdownStoreSymbolType > > > targets ) { + if (! getStates().count(from)) + throw AutomatonException("State \"" + std::to_string ( from ) + "\" doesn't exist."); + + if (input.template is < InputSymbolType >() && ! getInputAlphabet().count(input.template get < InputSymbolType >())) + throw AutomatonException("Input symbol \"" + std::to_string ( input.template get < InputSymbolType >() ) + "\" doesn't exist."); + + if (! getPushdownStoreAlphabet().count(pop)) + throw AutomatonException("Pushdown store symbol \"" + std::to_string ( pop ) + "\" doesn't exist."); + + for ( const std::pair < StateType, std::vector < PushdownStoreSymbolType > > & target : targets ) { + if ( ! getStates ( ).count ( target.first ) ) + throw AutomatonException("State \"" + std::to_string ( target.first ) + "\" doesn't exist."); + + for ( const PushdownStoreSymbolType & pushSymbol : target.second ) + if ( ! getPushdownStoreAlphabet().count(pushSymbol)) + throw AutomatonException("Pushdown store symbol \"" + std::to_string ( pushSymbol ) + "\" doesn't exist."); + } + + std::tuple<StateType, std::variant < EpsilonType, InputSymbolType >, PushdownStoreSymbolType> key(std::move(from), std::move(input), std::move(pop)); + transitions [ std::move ( key ) ].insert ( std::make_moveable_set ( targets ).begin ( ), std::make_moveable_set ( targets ).end ( ) ); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void SinglePopNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addTransitions(StateType from, InputSymbolType input, PushdownStoreSymbolType pop, std::set < std::pair < StateType, std::vector < PushdownStoreSymbolType > > > targets) { + std::variant < EpsilonType, InputSymbolType > inputVariant(std::move(input)); + addTransitions(std::move(from), std::move(inputVariant), std::move(pop), std::move ( targets ) ); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void SinglePopNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::addTransitions(StateType from, PushdownStoreSymbolType pop, std::set < std::pair < StateType, std::vector < PushdownStoreSymbolType > > >targets ) { + auto inputVariant = std::variant < EpsilonType, InputSymbolType >::template from < EpsilonType > ( ); + addTransitions(std::move(from), std::move(inputVariant), std::move(pop), std::move ( targets ) ); +} + template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > bool SinglePopNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType >::removeTransition(const StateType& from, const std::variant < EpsilonType, InputSymbolType >& input, const PushdownStoreSymbolType& pop, const StateType& to, const std::vector<PushdownStoreSymbolType>& push) { std::tuple<StateType, std::variant < EpsilonType, InputSymbolType >, PushdownStoreSymbolType> key(from, input, pop); diff --git a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h index ce801c4711..41ef1c8b53 100644 --- a/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h +++ b/alib2data/src/automaton/PDA/VisiblyPushdownNPDA.h @@ -220,6 +220,33 @@ public: */ bool addLocalTransition ( StateType current, InputSymbolType input, StateType next ); + /** + * Adds call transition defined by parameters to the automaton. + * @param current current state + * @param input input symbol + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addCallTransitions ( StateType current, InputSymbolType input, std::set < std::pair < StateType, PushdownStoreSymbolType > > targets ); + + /** + * Adds return transition defined by parameters to the automaton. + * @param current current state + * @param input input symbol + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addReturnTransitions ( StateType current, InputSymbolType input, PushdownStoreSymbolType pop, std::set < StateType > next ); + + /** + * Adds local transition defined by parameters to the automaton. + * @param current current state + * @param input input symbol + * @param next next state + * @throws AutomatonException when transition already exists or when transition contains state or symbol not present in the automaton + */ + void addLocalTransitions ( StateType current, InputSymbolType input, std::set < StateType > next ); + /** * Removes call transition from the automaton. * @param transition transition to remove @@ -358,6 +385,59 @@ bool VisiblyPushdownNPDA < InputSymbolType, PushdownStoreSymbolType, StateType > return localTransitions[std::move(key)].insert(std::move(to)).second; } +template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > +void VisiblyPushdownNPDA < InputSymbolType, PushdownStoreSymbolType, StateType >::addCallTransitions(StateType from, InputSymbolType input, std::set < std::pair < StateType, PushdownStoreSymbolType > > targets ) { + if ( ! getStates().count(from)) + throw AutomatonException("State \"" + std::to_string ( from ) + "\" doesn't exist."); + + if ( ! getCallInputAlphabet().count(input)) + throw AutomatonException("Input symbol \"" + std::to_string ( input ) + "\" doesn't exist."); + + for ( const std::pair < StateType, PushdownStoreSymbolType > & target : targets ) { + if ( ! getStates().count ( target.first ) ) + throw AutomatonException("State \"" + std::to_string ( target.first ) + "\" doesn't exist."); + + if ( ! getPushdownStoreAlphabet().count ( target.second ) ) + throw AutomatonException("Pushdown store symbol \"" + std::to_string ( target.second ) + "\" doesn't exist."); + } + + std::pair<StateType, InputSymbolType> key(std::move(from), std::move(input)); + callTransitions[std::move(key)].insert ( std::make_moveable_set ( targets ).begin ( ), std::make_moveable_set ( targets ).end ( ) ); +} + +template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > +void VisiblyPushdownNPDA < InputSymbolType, PushdownStoreSymbolType, StateType >::addReturnTransitions(StateType from, InputSymbolType input, PushdownStoreSymbolType pop, std::set < StateType > to) { + if (! getStates().count(from)) + throw AutomatonException("State \"" + std::to_string ( from ) + "\" doesn't exist."); + + if (! getReturnInputAlphabet().count(input)) + throw AutomatonException("Input symbol \"" + std::to_string ( input ) + "\" doesn't exist."); + + if (! getPushdownStoreAlphabet().count(pop)) + throw AutomatonException("Pushdown store symbol \"" + std::to_string ( pop ) + "\" doesn't exist."); + + if ( !std::includes ( getStates ( ).begin ( ), getStates ( ).end ( ), to.begin ( ), to.end ( ) ) ) + throw AutomatonException ( "Some target states don't exist." ); + + std::tuple<StateType, InputSymbolType, PushdownStoreSymbolType> key(std::move(from), std::move(input), std::move(pop)); + returnTransitions[std::move(key)].insert ( std::make_moveable_set ( to ).begin ( ), std::make_moveable_set ( to ).end ( ) ); +} + +template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > +void VisiblyPushdownNPDA < InputSymbolType, PushdownStoreSymbolType, StateType >::addLocalTransitions(StateType from, InputSymbolType input, std::set < StateType > to) { + if (! getStates().count(from)) + throw AutomatonException("State \"" + std::to_string ( from ) + "\" doesn't exist."); + + if (! getLocalInputAlphabet().count(input)) + throw AutomatonException("Input symbol \"" + std::to_string ( input ) + "\" doesn't exist."); + + if ( !std::includes ( getStates ( ).begin ( ), getStates ( ).end ( ), to.begin ( ), to.end ( ) ) ) + throw AutomatonException ( "Some target states don't exist." ); + + std::pair<StateType, InputSymbolType> key(std::move(from), std::move(input)); + localTransitions[std::move(key)].insert ( std::make_moveable_set ( to ).begin ( ), std::make_moveable_set ( to ).end ( ) ); +} + template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > bool VisiblyPushdownNPDA < InputSymbolType, PushdownStoreSymbolType, StateType >::removeCallTransition(const StateType& from, const InputSymbolType& input, const StateType& to, const PushdownStoreSymbolType& push) { std::pair<StateType, InputSymbolType> key(from, input); -- GitLab