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