diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.cpp b/alib2algo/src/automaton/simplify/SingleInitialState.cpp index 5cb4ef02e94006ed638772daf95b433a929ceaec..bc1112c23726d6271ca5f6341f6eb62b488952fa 100644 --- a/alib2algo/src/automaton/simplify/SingleInitialState.cpp +++ b/alib2algo/src/automaton/simplify/SingleInitialState.cpp @@ -8,17 +8,14 @@ #include "SingleInitialState.h" #include <registration/AlgoRegistration.hpp> -namespace automaton { +namespace { -namespace simplify { +auto SingleInitialStateMultiInitialStateNFA = registration::AbstractRegister < automaton::simplify::SingleInitialState, automaton::NFA < >, const automaton::MultiInitialStateNFA < > & > ( automaton::simplify::SingleInitialState::convert ); +auto SingleInitialStateMultiInitialStateEpsilonNFA = registration::AbstractRegister < automaton::simplify::SingleInitialState, automaton::EpsilonNFA < >, const automaton::MultiInitialStateEpsilonNFA < > & > ( automaton::simplify::SingleInitialState::convert ); +auto SingleInitialStateDFA = registration::AbstractRegister < automaton::simplify::SingleInitialState, automaton::DFA < >, const automaton::DFA < > & > ( automaton::simplify::SingleInitialState::convert ); +auto SingleInitialStateEpsilonNFA = registration::AbstractRegister < automaton::simplify::SingleInitialState, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( automaton::simplify::SingleInitialState::convert ); +auto SingleInitialStateNFA = registration::AbstractRegister < automaton::simplify::SingleInitialState, automaton::NFA < >, const automaton::NFA < > & > ( automaton::simplify::SingleInitialState::convert ); +auto SingleInitialStateCompactNFA = registration::AbstractRegister < automaton::simplify::SingleInitialState, automaton::CompactNFA < >, const automaton::CompactNFA < > & > ( automaton::simplify::SingleInitialState::convert ); +auto SingleInitialStateExtendedNFA = registration::AbstractRegister < automaton::simplify::SingleInitialState, automaton::ExtendedNFA < >, const automaton::ExtendedNFA < > & > ( automaton::simplify::SingleInitialState::convert ); -auto SingleInitialStateMultiInitialStateNFA = registration::AbstractRegister < SingleInitialState, automaton::NFA < >, const automaton::MultiInitialStateNFA < > & > ( SingleInitialState::convert ); -auto SingleInitialStateDFA = registration::AbstractRegister < SingleInitialState, automaton::DFA < >, const automaton::DFA < > & > ( SingleInitialState::convert ); -auto SingleInitialStateEpsilonNFA = registration::AbstractRegister < SingleInitialState, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( SingleInitialState::convert ); -auto SingleInitialStateNFA = registration::AbstractRegister < SingleInitialState, automaton::NFA < >, const automaton::NFA < > & > ( SingleInitialState::convert ); -auto SingleInitialStateCompactNFA = registration::AbstractRegister < SingleInitialState, automaton::CompactNFA < >, const automaton::CompactNFA < > & > ( SingleInitialState::convert ); -auto SingleInitialStateExtendedNFA = registration::AbstractRegister < SingleInitialState, automaton::ExtendedNFA < >, const automaton::ExtendedNFA < > & > ( SingleInitialState::convert ); - -} /* namespace simplify */ - -} /* namespace automaton */ +} /* namespace */ diff --git a/alib2algo/src/automaton/simplify/SingleInitialState.h b/alib2algo/src/automaton/simplify/SingleInitialState.h index 429f4d719544820f9ee006ece48f887d1eb6a24d..715bd9303928a975e60d5345b9ad30f1d29e3113 100644 --- a/alib2algo/src/automaton/simplify/SingleInitialState.h +++ b/alib2algo/src/automaton/simplify/SingleInitialState.h @@ -14,6 +14,7 @@ #include <automaton/FSM/DFA.h> #include <automaton/FSM/NFA.h> #include <automaton/FSM/MultiInitialStateNFA.h> +#include <automaton/FSM/MultiInitialStateEpsilonNFA.h> #include <automaton/FSM/ExtendedNFA.h> #include <automaton/FSM/EpsilonNFA.h> #include <automaton/FSM/CompactNFA.h> @@ -36,6 +37,8 @@ public: */ template < class SymbolType, class StateType > static automaton::NFA < SymbolType, StateType > convert(const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton); + template < class SymbolType, class EpsilonType, class StateType > + static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > convert(const automaton::MultiInitialStateEpsilonNFA < SymbolType, EpsilonType, StateType > & automaton); template < class SymbolType, class StateType > static automaton::DFA < SymbolType, StateType > convert(const automaton::DFA < SymbolType, StateType > & automaton); template < class SymbolType, class StateType > @@ -53,34 +56,61 @@ automaton::NFA < SymbolType, StateType > SingleInitialState::convert(const autom // step 1, 3 StateType q0 = common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), automaton.getStates ( ) ); - automaton::NFA < SymbolType, StateType > res(q0); - res.setInputAlphabet(automaton.getInputAlphabet()); - for(const auto& q : automaton.getStates()) - res.addState(q); + automaton::NFA < SymbolType, StateType > res ( q0 ); + res.setInputAlphabet ( automaton.getInputAlphabet ( ) ); + + for( const StateType & q : automaton.getStates ( ) ) + res.addState( q ); + + // step 2 + for ( const auto & q : automaton.getInitialStates ( ) ) + for(const auto & kv : automaton.getTransitionsFromState ( q ) ) + for ( const StateType & to : kv.second ) + res.addTransition ( q0, kv.first.second, to ); + + for ( const auto & t : automaton.getTransitions ( ) ) + for ( const auto & q : t.second ) + res.addTransition ( t.first.first, t.first.second, q ); + + // step 4, 5 + ext::set < StateType > intersection; + std::set_intersection ( res.getFinalStates ( ).begin ( ), res.getFinalStates ( ).end ( ), automaton.getInitialStates ( ).begin ( ), automaton.getInitialStates ( ).end ( ), std::inserter ( intersection, intersection.begin ( ) ) ); + + res.setFinalStates ( automaton.getFinalStates ( ) ); + if ( intersection.size ( ) != 0 ) + res.addFinalState ( q0 ); + + return res; +} + +template < class SymbolType, class EpsilonType, class StateType > +automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > SingleInitialState::convert(const automaton::MultiInitialStateEpsilonNFA < SymbolType, EpsilonType, StateType > & automaton) { + // step 1, 3 + StateType q0 = common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), automaton.getStates ( ) ); + + automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > res ( q0 ); + res.setInputAlphabet ( automaton.getInputAlphabet ( ) ); + + for( const StateType & q : automaton.getStates ( ) ) + res.addState( q ); // step 2 - for(const auto& q : automaton.getInitialStates()) { - for(const auto& kv: automaton.getTransitionsFromState(q)) { - for(const auto& to : kv.second) { - res.addTransition(q0, kv.first.second, to); - } - } - } - - for(const auto& t : automaton.getTransitions()) { - for(const auto& q : t.second) { - res.addTransition(t.first.first, t.first.second, q); - } - } + for ( const auto & q : automaton.getInitialStates ( ) ) + for(const auto & kv : automaton.getTransitionsFromState ( q ) ) + for ( const StateType & to : kv.second ) + res.addTransition ( q0, kv.first.second, to ); + + for ( const auto & t : automaton.getTransitions ( ) ) + for ( const StateType & q : t.second ) + res.addTransition ( t.first.first, t.first.second, q ); // step 4, 5 - ext::set<StateType> intersection; - std::set_intersection(res.getFinalStates().begin(), res.getFinalStates().end(), automaton.getInitialStates().begin(), automaton.getInitialStates().end(), std::inserter(intersection, intersection.begin())); + ext::set < StateType > intersection; + std::set_intersection ( res.getFinalStates ( ).begin ( ), res.getFinalStates ( ).end ( ), automaton.getInitialStates ( ).begin ( ), automaton.getInitialStates ( ).end ( ), std::inserter ( intersection, intersection.begin ( ) ) ); - res.setFinalStates(automaton.getFinalStates()); - if(intersection.size() != 0) { - res.addFinalState(q0); - } + res.setFinalStates ( automaton.getFinalStates ( ) ); + if ( intersection.size ( ) != 0 ) + res.addFinalState ( q0 ); return res; } diff --git a/alib2algo/src/automaton/simplify/SingleInitialStateEpsilonTransition.cpp b/alib2algo/src/automaton/simplify/SingleInitialStateEpsilonTransition.cpp new file mode 100644 index 0000000000000000000000000000000000000000..875ceb709647672fd2d754cfbd3cec69c34ed36d --- /dev/null +++ b/alib2algo/src/automaton/simplify/SingleInitialStateEpsilonTransition.cpp @@ -0,0 +1,21 @@ +/* + * SingleInitialStateEpsilonTransition.cpp + * + * Created on: 6. 6. 2018 + * Author: Jan Travnicek + */ + +#include "SingleInitialStateEpsilonTransition.h" +#include <registration/AlgoRegistration.hpp> + +namespace { + +auto SingleInitialStateMultiInitialStateNFA = registration::AbstractRegister < automaton::simplify::SingleInitialStateEpsilonTransition, automaton::EpsilonNFA < >, const automaton::MultiInitialStateNFA < > & > ( automaton::simplify::SingleInitialStateEpsilonTransition::convert ); +auto SingleInitialStateMultiInitialStateEpsilonNFA = registration::AbstractRegister < automaton::simplify::SingleInitialStateEpsilonTransition, automaton::EpsilonNFA < >, const automaton::MultiInitialStateEpsilonNFA < > & > ( automaton::simplify::SingleInitialStateEpsilonTransition::convert ); +auto SingleInitialStateDFA = registration::AbstractRegister < automaton::simplify::SingleInitialStateEpsilonTransition, automaton::DFA < >, const automaton::DFA < > & > ( automaton::simplify::SingleInitialStateEpsilonTransition::convert ); +auto SingleInitialStateEpsilonNFA = registration::AbstractRegister < automaton::simplify::SingleInitialStateEpsilonTransition, automaton::EpsilonNFA < >, const automaton::EpsilonNFA < > & > ( automaton::simplify::SingleInitialStateEpsilonTransition::convert ); +auto SingleInitialStateNFA = registration::AbstractRegister < automaton::simplify::SingleInitialStateEpsilonTransition, automaton::NFA < >, const automaton::NFA < > & > ( automaton::simplify::SingleInitialStateEpsilonTransition::convert ); +auto SingleInitialStateCompactNFA = registration::AbstractRegister < automaton::simplify::SingleInitialStateEpsilonTransition, automaton::CompactNFA < >, const automaton::CompactNFA < > & > ( automaton::simplify::SingleInitialStateEpsilonTransition::convert ); +auto SingleInitialStateExtendedNFA = registration::AbstractRegister < automaton::simplify::SingleInitialStateEpsilonTransition, automaton::ExtendedNFA < >, const automaton::ExtendedNFA < > & > ( automaton::simplify::SingleInitialStateEpsilonTransition::convert ); + +} /* namespace */ diff --git a/alib2algo/src/automaton/simplify/SingleInitialStateEpsilonTransition.h b/alib2algo/src/automaton/simplify/SingleInitialStateEpsilonTransition.h new file mode 100644 index 0000000000000000000000000000000000000000..22e590b75f67347d95f5d4385907b0923ec3af6d --- /dev/null +++ b/alib2algo/src/automaton/simplify/SingleInitialStateEpsilonTransition.h @@ -0,0 +1,130 @@ +/* + * SingleInitialStateEpsilonTransition.h + * + * Created on: 6. 6. 2018 + * Author: Jan Travnicek + */ + +#ifndef _SINGLE_INITIAL_STATE_H_ +#define _SINGLE_INITIAL_STATE_H_ + +#include <automaton/FSM/DFA.h> +#include <automaton/FSM/NFA.h> +#include <automaton/FSM/MultiInitialStateNFA.h> +#include <automaton/FSM/MultiInitialStateEpsilonNFA.h> +#include <automaton/FSM/ExtendedNFA.h> +#include <automaton/FSM/EpsilonNFA.h> +#include <automaton/FSM/CompactNFA.h> + +#include <label/InitialStateLabel.h> +#include <common/createUnique.hpp> + +namespace automaton { + +namespace simplify { + +/** + * Makes finite automaton's transition function convert. + * Source: Melichar: Algorithm 2.22 + */ +class SingleInitialStateEpsilonTransition { +public: + /** + * Computes epsilon closure of a state in epsilon nonfree automaton + */ + template < class SymbolType, class StateType > + static automaton::EpsilonNFA < SymbolType, DefaultEpsilonType, StateType > convert(const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton); + template < class SymbolType, class EpsilonType, class StateType > + static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > convert(const automaton::MultiInitialStateEpsilonNFA < SymbolType, EpsilonType, StateType > & automaton); + template < class SymbolType, class StateType > + static automaton::DFA < SymbolType, StateType > convert(const automaton::DFA < SymbolType, StateType > & automaton); + template < class SymbolType, class StateType > + static automaton::NFA < SymbolType, StateType > convert(const automaton::NFA < SymbolType, StateType > & automaton); + template < class SymbolType, class EpsilonType, class StateType > + static automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > convert(const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton); + template < class SymbolType, class StateType > + static automaton::ExtendedNFA < SymbolType, StateType > convert(const automaton::ExtendedNFA < SymbolType, StateType > & automaton); + template < class SymbolType, class StateType > + static automaton::CompactNFA < SymbolType, StateType > convert(const automaton::CompactNFA < SymbolType, StateType > & automaton); +}; + +template < class SymbolType, class StateType > +automaton::EpsilonNFA < SymbolType, DefaultEpsilonType, StateType > SingleInitialStateEpsilonTransition::convert(const automaton::MultiInitialStateNFA < SymbolType, StateType > & automaton) { + // step 1, 3 + StateType q0 = common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), automaton.getStates ( ) ); + + automaton::EpsilonNFA < SymbolType, DefaultEpsilonType, StateType > res ( q0 ); + res.setInputAlphabet ( automaton.getInputAlphabet ( ) ); + + for( const StateType & q : automaton.getStates ( ) ) + res.addState( q ); + + // step 2 + for ( const auto & q : automaton.getInitialStates ( ) ) + res.addTransition ( q0, q ); + + for ( const auto & t : automaton.getTransitions ( ) ) + for ( const auto & q : t.second ) + res.addTransition ( t.first.first, t.first.second, q ); + + // step 4, 5 + res.setFinalStates ( automaton.getFinalStates ( ) ); + + return res; +} + +template < class SymbolType, class EpsilonType, class StateType > +automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > SingleInitialStateEpsilonTransition::convert(const automaton::MultiInitialStateEpsilonNFA < SymbolType, EpsilonType, StateType > & automaton) { + // step 1, 3 + StateType q0 = common::createUnique ( label::InitialStateLabel::instance < StateType > ( ), automaton.getStates ( ) ); + + automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > res ( q0 ); + res.setInputAlphabet ( automaton.getInputAlphabet ( ) ); + + for( const StateType & q : automaton.getStates ( ) ) + res.addState( q ); + + // step 2 + for ( const auto & q : automaton.getInitialStates ( ) ) + res.addTransition ( q0, q ); + + for ( const auto & t : automaton.getTransitions ( ) ) + for ( const StateType & q : t.second ) + res.addTransition ( t.first.first, t.first.second, q ); + + // step 4, 5 + res.setFinalStates ( automaton.getFinalStates ( ) ); + + return res; +} + +template < class SymbolType, class StateType > +automaton::DFA < SymbolType, StateType > SingleInitialStateEpsilonTransition::convert(const automaton::DFA < SymbolType, StateType > & automaton) { + return automaton; +} + +template < class SymbolType, class EpsilonType, class StateType > +automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > SingleInitialStateEpsilonTransition::convert(const automaton::EpsilonNFA < SymbolType, EpsilonType, StateType > & automaton) { + return automaton; +} + +template < class SymbolType, class StateType > +automaton::NFA < SymbolType, StateType > SingleInitialStateEpsilonTransition::convert(const automaton::NFA < SymbolType, StateType > & automaton) { + return automaton; +} + +template < class SymbolType, class StateType > +automaton::CompactNFA < SymbolType, StateType > SingleInitialStateEpsilonTransition::convert(const automaton::CompactNFA < SymbolType, StateType > & automaton) { + return automaton; +} + +template < class SymbolType, class StateType > +automaton::ExtendedNFA < SymbolType, StateType > SingleInitialStateEpsilonTransition::convert(const automaton::ExtendedNFA < SymbolType, StateType > & automaton) { + return automaton; +} + +} /* namespace simplify */ + +} /* namespace automaton */ + +#endif /* _SINGLE_INITIAL_STATE_H_ */