diff --git a/alib2algo/src/automaton/determinize/Determinize.cpp b/alib2algo/src/automaton/determinize/Determinize.cpp index 0673643be40811eb9def9de5db37cd4c59347bf3..809eed6fa3cbefd7a0ac53a2720a53efa0830286 100644 --- a/alib2algo/src/automaton/determinize/Determinize.cpp +++ b/alib2algo/src/automaton/determinize/Determinize.cpp @@ -14,7 +14,6 @@ #include <automaton/PDA/InputDrivenNPDA.h> #include <automaton/PDA/SinglePopDPDA.h> #include <automaton/PDA/VisiblyPushdownDPDA.h> -#include <automaton/PDA/RealTimeHeightDeterministicDPDA.h> #include <automaton/TM/OneTapeDTM.h> #include <automaton/TA/DFTA.h> #include <automaton/PDA/RealTimeHeightDeterministicNPDA.h> @@ -43,9 +42,13 @@ auto DeterminizeInputDrivenNPDA = registration::AbstractRegister < Determinize, auto DeterminizeVisiblyPushdownDPDA = registration::AbstractRegister < Determinize, automaton::VisiblyPushdownDPDA < >, const automaton::VisiblyPushdownDPDA < > & > ( Determinize::determinize ); +auto DeterminizeVisiblyPushdownNPDA = registration::AbstractRegister < Determinize, automaton::VisiblyPushdownDPDA < DefaultSymbolType, ext::pair < ext::set < ext::pair < DefaultStateType, DefaultStateType > >, DefaultSymbolType >, ext::set < ext::pair < DefaultStateType, DefaultStateType > > >, const automaton::VisiblyPushdownNPDA < > & > ( Determinize::determinize ); + auto DeterminizeRealTimeHeightDeterministicDPDA = registration::AbstractRegister < Determinize, automaton::RealTimeHeightDeterministicDPDA < >, const automaton::RealTimeHeightDeterministicDPDA < > & > ( Determinize::determinize ); +auto DeterminizeRealTimeHeightDeterministicNPDA = registration::AbstractRegister < Determinize, automaton::RealTimeHeightDeterministicDPDA < DefaultSymbolType, DefaultEpsilonType, ext::pair < ext::set < ext::pair < DefaultStateType, DefaultStateType > >, ext::variant < DefaultEpsilonType, DefaultSymbolType > >, ext::set < ext::pair < DefaultStateType, DefaultStateType > > >, const automaton::RealTimeHeightDeterministicNPDA < > & > ( Determinize::determinize ); + auto DeterminizeSinglePopDPDA = registration::AbstractRegister < Determinize, automaton::SinglePopDPDA < >, const automaton::SinglePopDPDA < > & > ( Determinize::determinize ); @@ -61,7 +64,3 @@ auto DeterminizeOneTapeDTM = registration::AbstractRegister < Determinize, autom } /* namespace determinize */ } /* namespace automaton */ - -#include "DeterminizeVPAPart.cxx" -#include "DeterminizeRHDPDAPart.cxx" - diff --git a/alib2algo/src/automaton/determinize/Determinize.h b/alib2algo/src/automaton/determinize/Determinize.h index d1e4951a1c2fc32e3b07d2647c1bab0e65af9ea9..f7dd25cab76299c8bba11de8a1d5ed10df22429b 100644 --- a/alib2algo/src/automaton/determinize/Determinize.h +++ b/alib2algo/src/automaton/determinize/Determinize.h @@ -16,6 +16,9 @@ #include <automaton/transform/PDAToRHPDA.h> #include <automaton/transform/RHPDAToPDA.h> +#include <automaton/PDA/RealTimeHeightDeterministicDPDA.h> +#include <automaton/PDA/DPDA.h> + namespace automaton { namespace determinize { @@ -54,12 +57,14 @@ public: template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > static automaton::VisiblyPushdownDPDA < InputSymbolType, PushdownStoreSymbolType, StateType > determinize ( const automaton::VisiblyPushdownDPDA < InputSymbolType, PushdownStoreSymbolType, StateType > & nondeterministic ); - static automaton::VisiblyPushdownDPDA < > determinize ( const automaton::VisiblyPushdownNPDA < > & nondeterministic ); + template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > + static automaton::VisiblyPushdownDPDA < InputSymbolType, ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType >, ext::set < ext::pair < StateType, StateType > > > determinize ( const automaton::VisiblyPushdownNPDA < InputSymbolType, PushdownStoreSymbolType, StateType > & nondeterministic ); template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > static automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > determinize ( const automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > & nondeterministic ); - static automaton::RealTimeHeightDeterministicDPDA < > determinize ( const automaton::RealTimeHeightDeterministicNPDA < > & nondeterministic ); + template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > + static automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > >, ext::set < ext::pair < StateType, StateType > > > determinize ( const automaton::RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > & nondeterministic ); template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > static automaton::SinglePopDPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > determinize ( const automaton::SinglePopDPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > & dpda ); @@ -112,8 +117,9 @@ automaton::DPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateTy template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > automaton::DPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > Determinize::determinize ( const automaton::NPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > & automaton ) { automaton::RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > rhpda = automaton::PDAToRHPDA::convert(automaton); - automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > dpda = Determinize::determinize(rhpda); - return automaton::RHPDAToPDA::convert ( dpda ); + automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > >, ext::set < ext::pair < StateType, StateType > > > dpda = Determinize::determinize(rhpda); + automaton::RealTimeHeightDeterministicDPDA < > norm = core::normalize < decltype ( dpda ) >::eval ( std::move ( dpda ) ); + return automaton::RHPDAToPDA::convert ( norm ); } template < class SymbolType, class StateType > @@ -128,5 +134,7 @@ automaton::OneTapeDTM < SymbolType, StateType > Determinize::determinize ( const #include "DeterminizeNFAPart.hxx" #include "DeterminizeIDPDAPart.hxx" #include "DeterminizeNFTAPart.hxx" +#include "DeterminizeVPAPart.hxx" +#include "DeterminizeRHDPDAPart.hxx" #endif /* DETERMINIZE_H_ */ diff --git a/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx deleted file mode 100644 index 00cd9267bdfa9a96a9070f1a916de634a2c79adb..0000000000000000000000000000000000000000 --- a/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.cxx +++ /dev/null @@ -1,284 +0,0 @@ -/* - * NFADeterminizer.cpp - * - * Created on: 16. 1. 2014 - * Author: Jan Travnicek - */ - -#include "common/RHDPDACommon.h" - -#include <automaton/PDA/RealTimeHeightDeterministicNPDA.h> -#include <alib/set> -#include <global/GlobalData.h> - -namespace automaton { - -namespace determinize { - -void addRetTransition(const DefaultStateType& from, const ext::variant<DefaultEpsilonType, DefaultSymbolType>& input, const DefaultSymbolType& dvpdaSymbol, const DefaultStateType& to, automaton::RealTimeHeightDeterministicDPDA < > & deterministic) { - deterministic.addState(from); - deterministic.addState(to); - deterministic.addPushdownStoreSymbol(dvpdaSymbol); - - deterministic.addReturnTransition(from, input, dvpdaSymbol, to); -} - -void retInitial(const DefaultStateType& state, const DefaultSymbolType& pdaSymbol, const ext::variant<DefaultEpsilonType, DefaultSymbolType>& input, const automaton::RealTimeHeightDeterministicNPDA < > & nondeterministic, automaton::RealTimeHeightDeterministicDPDA < > & deterministic, ext::map<ext::tuple<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>, DefaultSymbolType>, DefaultStateType>& rubbishReturnTransitions) { - const ext::set<ext::pair<DefaultStateType, DefaultStateType>> & S = unpackFromStateLabel(state); - - ext::set<ext::pair<DefaultStateType, DefaultStateType>> S1; - for(const auto& entry : S) { - const DefaultStateType& q = entry.first; - const DefaultStateType& q2 = entry.second; - - for(const auto& transition : nondeterministic.getReturnTransitions()) { - if(q2 != std::get<0>(transition.first)) continue; - if(input != std::get<1>(transition.first)) continue; - if(nondeterministic.getBottomOfTheStackSymbol() != std::get<2>(transition.first)) continue; - - for(const auto& to : transition.second) { - const DefaultStateType& q1 = to; - S1.insert(ext::make_pair(q, q1)); - } - } - } - - bool S1Empty = S1.empty(); - DefaultStateType to(packToStateLabel(std::move(S1))); - if(S1Empty) { - ext::tuple<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>, DefaultSymbolType> key(state, input, pdaSymbol); - rubbishReturnTransitions.insert(std::make_pair(key, to)); - } else { - addRetTransition(state, input, pdaSymbol, to, deterministic); - } -} - -void ret(const DefaultStateType& state, const DefaultSymbolType& pdaSymbol, const ext::variant<DefaultEpsilonType, DefaultSymbolType>& input, const automaton::RealTimeHeightDeterministicNPDA < > & nondeterministic, automaton::RealTimeHeightDeterministicDPDA < > & deterministic, ext::map<ext::tuple<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>, DefaultSymbolType>, DefaultStateType>& rubbishReturnTransitions) { - const ext::set<ext::pair<DefaultStateType, DefaultStateType>> & S = unpackFromStateLabel(state); - const ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>> & pdaSymbolUnpack = unpackFromDRHDPDAStackSymbol(pdaSymbol); - const ext::set<ext::pair<DefaultStateType, DefaultStateType>>& S1 = unpackFromStateLabel ( pdaSymbolUnpack.first ); - - ext::set<ext::pair<DefaultStateType, DefaultStateType>> update; - - for(const auto& transition : nondeterministic.getCallTransitions()) { - if(pdaSymbolUnpack.second != std::get<1>(transition.first)) continue; - - const DefaultStateType& q = std::get<0>(transition.first); - for(const auto& to : transition.second) { - const DefaultStateType& q1 = to.first; - const DefaultSymbolType& gamma = to.second; - - for(const auto& entry : S) { - if(q1 != entry.first) continue; - const DefaultStateType& q2 = entry.second; - - for(const auto& transition2 : nondeterministic.getReturnTransitions()) { - if(q2 != std::get<0>(transition2.first)) continue; - if(input != std::get<1>(transition2.first)) continue; - if(gamma != std::get<2>(transition2.first)) continue; - - for(const auto& to2 : transition2.second) { - const DefaultStateType& qI = to2; - - update.insert(ext::make_pair(q, qI)); - } - } - } - } - } - - ext::set<ext::pair<DefaultStateType, DefaultStateType>> S2; - for(const auto& entry : S1) { - const DefaultStateType& q = entry.first; - const DefaultStateType& q3 = entry.second; - for(const auto& entry2 : update) { - if(q3 != entry2.first) continue; - - const DefaultStateType& qI = entry2.second; - - S2.insert(ext::make_pair(q, qI)); - } - } - - bool S2Empty = S2.empty(); - DefaultStateType to(packToStateLabel(std::move(S2))); - if(S2Empty) { - ext::tuple<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>, DefaultSymbolType> key(state, input, pdaSymbol); - rubbishReturnTransitions.insert(std::make_pair(key, to)); - } else { - addRetTransition(state, input, pdaSymbol, to, deterministic); - } -} - -void addCallTransition(const DefaultStateType& from, const ext::variant<DefaultEpsilonType, DefaultSymbolType>& input, const DefaultStateType& to, const DefaultSymbolType& dvpdaSymbol, automaton::RealTimeHeightDeterministicDPDA < > & deterministic) { - deterministic.addState(from); - deterministic.addState(to); - deterministic.addPushdownStoreSymbol(dvpdaSymbol); - - deterministic.addCallTransition(from, input, to, dvpdaSymbol); -} - -void call(const DefaultStateType& state, const ext::variant<DefaultEpsilonType, DefaultSymbolType>& input, const automaton::RealTimeHeightDeterministicNPDA < > & nondeterministic, automaton::RealTimeHeightDeterministicDPDA < > & deterministic, ext::map<ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>>, ext::pair<DefaultStateType, DefaultSymbolType> >& rubbishCallTransitions) { - const ext::set<ext::pair<DefaultStateType, DefaultStateType>> & S = unpackFromStateLabel(state); - - ext::set<DefaultStateType> R = retrieveDSubSet(S); - ext::set<DefaultStateType> R1; - - for(const DefaultStateType& q : R) { - for(const auto& transition : nondeterministic.getCallTransitions()) { - if(q != transition.first.first) continue; - if(input != transition.first.second) continue; - - for(const auto& to : transition.second) { - const DefaultStateType& q1 = to.first; - - R1.insert(q1); - } - } - } - - bool R1Empty = R1.empty(); - DefaultStateType to = packToStateLabel(createIdentity(std::move(R1))); - DefaultSymbolType push = packToStackSymbolLabel(ext::make_pair(state, input)); - if(R1Empty) { - rubbishCallTransitions.insert(std::make_pair(ext::make_pair(state, input), ext::make_pair(to, push))); - } else { - addCallTransition(state, input, to, push, deterministic); - } -} - -void addLocalTransition(const DefaultStateType& from, const ext::variant<DefaultEpsilonType, DefaultSymbolType>& input, const DefaultStateType& to, automaton::RealTimeHeightDeterministicDPDA < > & deterministic) { - deterministic.addState(from); - deterministic.addState(to); - - deterministic.addLocalTransition(from, input, to); -} - -void local(const DefaultStateType& state, const ext::variant<DefaultEpsilonType, DefaultSymbolType>& input, const automaton::RealTimeHeightDeterministicNPDA < > & nondeterministic, automaton::RealTimeHeightDeterministicDPDA < > & deterministic, ext::map<ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>>, DefaultStateType>& rubbishLocalTransitions ) { - const ext::set<ext::pair<DefaultStateType, DefaultStateType>> & S = unpackFromStateLabel(state); - ext::set<ext::pair<DefaultStateType, DefaultStateType>> S1; - - for(const auto& entry : S) { - const DefaultStateType & q = entry.first; - const DefaultStateType & q2 = entry.second; - for(const auto& transition : nondeterministic.getLocalTransitions()) { - if(q2 != transition.first.first) continue; - if(input != transition.first.second) continue; - - for(const auto& to : transition.second) { - const DefaultStateType & q1 = to; - - S1.insert(ext::make_pair(q, q1)); - } - } - } - - bool S1Empty = S1.empty(); - DefaultStateType to(packToStateLabel(std::move(S1))); - if(S1Empty) { - rubbishLocalTransitions.insert(std::make_pair(ext::make_pair(state, input), to)); - } else { - addLocalTransition(state, input, to, deterministic); - } -} - -ext::tuple<ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>>, ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>>, ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>>> getLocalCallRetPartitioning(const automaton::RealTimeHeightDeterministicNPDA < > & n, const DefaultStateType& state) { - ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>> local; - ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>> call; - ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>> ret; - - const ext::set<DefaultStateType> dSubSet = retrieveDSubSet(unpackFromStateLabel(state)); - - for(const auto& transition : n.getLocalTransitions()) { - if(dSubSet.count(transition.first.first)) - local.insert(transition.first.second); - } - - for(const auto& transition : n.getCallTransitions()) { - if(dSubSet.count(transition.first.first)) - call.insert(transition.first.second); - } - - for(const auto& transition : n.getReturnTransitions()) { - if(dSubSet.count(std::get<0>(transition.first))) - ret.insert(std::get<1>(transition.first)); - } - - return ext::make_tuple(std::move(local), std::move(call), std::move(ret)); -} - -automaton::RealTimeHeightDeterministicDPDA < > Determinize::determinize(const automaton::RealTimeHeightDeterministicNPDA < > & n) { - DefaultStateType initialLabel = packToStateLabel(createIdentity(n.getInitialStates())); - - automaton::RealTimeHeightDeterministicDPDA < > d(initialLabel, n.getBottomOfTheStackSymbol()); - d.setInputAlphabet(n.getInputAlphabet()); - - ext::set<DefaultStateType> rubbishStates = {DefaultStateType(packToStateLabel({}))}; - ext::map<ext::tuple<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>, DefaultSymbolType>, DefaultStateType> rubbishReturnTransitions; - ext::map<ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>>, ext::pair<DefaultStateType, DefaultSymbolType> > rubbishCallTransitions; - ext::map<ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>>, DefaultStateType> rubbishLocalTransitions; - - for(;;) { - ext::set<ext::pair<DefaultStateType, DefaultSymbolType>> stateSymbols = existsDirtyStateSymbol(d, rubbishStates, rubbishCallTransitions, rubbishReturnTransitions, n); - ext::set<DefaultStateType> states = existsDirtyState(d, rubbishStates, rubbishCallTransitions, rubbishLocalTransitions, n); - - if(stateSymbols.empty() && states.empty()) break; - - for(const auto& stateSymbol : stateSymbols) { - if ( common::GlobalData::verbose ) - common::Streams::log << "Dirty state symbol: " << stateSymbol << std::endl; - - ext::tuple<ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>>, ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>>, ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>>> partitioning = getLocalCallRetPartitioning(n, stateSymbol.first); - - ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>>& retPart = std::get<2>(partitioning); - - for(const auto& symbol : retPart) { - if(stateSymbol.second == d.getBottomOfTheStackSymbol()) { - retInitial(stateSymbol.first, stateSymbol.second, symbol, n, d, rubbishReturnTransitions); - } else { - ret(stateSymbol.first, stateSymbol.second, symbol, n, d, rubbishReturnTransitions); - } - } - } - - for(const auto& state : states) { - if ( common::GlobalData::verbose ) - common::Streams::log << "Dirty state: " << state << std::endl; - ext::tuple<ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>>, ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>>, ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>>> partitioning = getLocalCallRetPartitioning(n, state); - - ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>>& localPart = std::get<0>(partitioning); - ext::set<ext::variant<DefaultEpsilonType, DefaultSymbolType>>& callPart = std::get<1>(partitioning); - - for(const auto& symbol : localPart) { - local(state, symbol, n, d, rubbishLocalTransitions); - } - for(const auto& symbol : callPart) { - call(state, symbol, n, d, rubbishCallTransitions); - } - } - } - - const ext::set<DefaultStateType>& finalLabels = n.getFinalStates(); - for(const DefaultStateType& state : d.getStates()) { - const ext::set<DefaultStateType> labels = retrieveDSubSet(unpackFromStateLabel(state)); - - if(!ext::excludes(finalLabels.begin(), finalLabels.end(), labels.begin(), labels.end())) { - d.addFinalState(state); - } - } - - if ( common::GlobalData::verbose ) { - common::Streams::log << "Rubbish states: " << rubbishStates << std::endl; - common::Streams::log << "Rubbish return transitions: " << rubbishReturnTransitions << std::endl; - common::Streams::log << "Rubbish call transitions: " << rubbishCallTransitions << std::endl; - common::Streams::log << "Rubbish local transitions:" << rubbishLocalTransitions << std::endl; - } - - return d; -} - -auto DeterminizeRealTimeHeightDeterministicNPDA = registration::AbstractRegister < Determinize, automaton::RealTimeHeightDeterministicDPDA < >, const automaton::RealTimeHeightDeterministicNPDA < > & > ( Determinize::determinize ); - -} /* namespace determinize */ - -} /* namespace automaton */ diff --git a/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.hxx b/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.hxx new file mode 100644 index 0000000000000000000000000000000000000000..56fc6fdb1fb054f68eb9d575e4a97e4fc1bbaac3 --- /dev/null +++ b/alib2algo/src/automaton/determinize/DeterminizeRHDPDAPart.hxx @@ -0,0 +1,295 @@ +/* + * NFADeterminizer.cpp + * + * Created on: 16. 1. 2014 + * Author: Jan Travnicek + */ + +#include "common/RHDPDACommon.h" + +#include <automaton/PDA/RealTimeHeightDeterministicNPDA.h> +#include <alib/set> +#include <global/GlobalData.h> + +namespace automaton { + +namespace determinize { + +template < class InputSymbolType, class EpsilonType, class StateType > +void addRetTransition(const ext::set < ext::pair < StateType, StateType > > & from, const ext::variant < EpsilonType, InputSymbolType > & input, const ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > > & dvpdaSymbol, const ext::set < ext::pair < StateType, StateType > > & to, automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > >, ext::set < ext::pair < StateType, StateType > > > & deterministic) { + deterministic.addState(from); + deterministic.addState(to); + deterministic.addPushdownStoreSymbol(dvpdaSymbol); + + deterministic.addReturnTransition(from, input, dvpdaSymbol, to); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void retInitial(const ext::set < ext::pair < StateType, StateType > > & state, const ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > > & pdaSymbol, const ext::variant < EpsilonType, InputSymbolType>& input, const automaton::RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > & nondeterministic, automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > >, ext::set < ext::pair < StateType, StateType > > > & deterministic, ext::map < ext::tuple < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType >, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > > >, ext::set < ext::pair < StateType, StateType > > > & rubbishReturnTransitions ) { + const ext::set<ext::pair<StateType, StateType>> & S = unpackFromStateLabel(state); + + ext::set<ext::pair<StateType, StateType>> S1; + for(const auto& entry : S) { + const StateType& q = entry.first; + const StateType& q2 = entry.second; + + for(const auto& transition : nondeterministic.getReturnTransitions()) { + if(q2 != std::get<0>(transition.first)) continue; + if(input != std::get<1>(transition.first)) continue; + if(nondeterministic.getBottomOfTheStackSymbol() != std::get<2>(transition.first)) continue; + + for(const auto& to : transition.second) { + const StateType& q1 = to; + S1.insert(ext::make_pair(q, q1)); + } + } + } + + bool S1Empty = S1.empty(); + auto to ( packToStateLabel ( std::move ( S1 ) ) ); + if(S1Empty) { + ext::tuple < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType >, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > > > key(state, input, pdaSymbol); + rubbishReturnTransitions.insert(std::make_pair(key, to)); + } else { + addRetTransition(state, input, pdaSymbol, to, deterministic); + } +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void ret(const ext::set < ext::pair < StateType, StateType > > & state, const ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > > & pdaSymbol, const ext::variant < EpsilonType, InputSymbolType > & input, const automaton::RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > & nondeterministic, automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > >, ext::set < ext::pair < StateType, StateType > > > & deterministic, ext::map < ext::tuple < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType >, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > > >, ext::set < ext::pair < StateType, StateType > > > & rubbishReturnTransitions) { + const ext::set<ext::pair<StateType, StateType>> & S = unpackFromStateLabel(state); + const ext::pair<ext::set < ext::pair < StateType, StateType > >, ext::variant<EpsilonType, InputSymbolType>> & pdaSymbolUnpack = unpackFromStackSymbol(pdaSymbol); + const ext::set<ext::pair<StateType, StateType>>& S1 = unpackFromStateLabel ( pdaSymbolUnpack.first ); + + ext::set<ext::pair<StateType, StateType>> update; + + for(const auto& transition : nondeterministic.getCallTransitions()) { + if(pdaSymbolUnpack.second != std::get<1>(transition.first)) continue; + + const StateType& q = std::get<0>(transition.first); + for(const auto& to : transition.second) { + const StateType& q1 = to.first; + const PushdownStoreSymbolType& gamma = to.second; + + for(const auto& entry : S) { + if(q1 != entry.first) continue; + const StateType& q2 = entry.second; + + for(const auto& transition2 : nondeterministic.getReturnTransitions()) { + if(q2 != std::get<0>(transition2.first)) continue; + if(input != std::get<1>(transition2.first)) continue; + if(gamma != std::get<2>(transition2.first)) continue; + + for(const auto& to2 : transition2.second) { + const StateType& qI = to2; + + update.insert(ext::make_pair(q, qI)); + } + } + } + } + } + + ext::set<ext::pair<StateType, StateType>> S2; + for(const auto& entry : S1) { + const StateType& q = entry.first; + const StateType& q3 = entry.second; + for(const auto& entry2 : update) { + if(q3 != entry2.first) continue; + + const StateType& qI = entry2.second; + + S2.insert(ext::make_pair(q, qI)); + } + } + + bool S2Empty = S2.empty(); + auto to ( packToStateLabel ( std::move ( S2 ) ) ); + if(S2Empty) { + ext::tuple < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType >, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > > > key(state, input, pdaSymbol); + rubbishReturnTransitions.insert(std::make_pair(key, to)); + } else { + addRetTransition(state, input, pdaSymbol, to, deterministic); + } +} + +template < class InputSymbolType, class EpsilonType, class StateType > +void addCallTransition(const ext::set < ext::pair < StateType, StateType > > & from, const ext::variant<EpsilonType, InputSymbolType > & input, const ext::set < ext::pair < StateType, StateType > > & to, const ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > > & dvpdaSymbol, automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > >, ext::set < ext::pair < StateType, StateType > > > & deterministic) { + deterministic.addState(from); + deterministic.addState(to); + deterministic.addPushdownStoreSymbol(dvpdaSymbol); + + deterministic.addCallTransition(from, input, to, dvpdaSymbol); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void call(const ext::set < ext::pair < StateType, StateType > > & state, const ext::variant < EpsilonType, InputSymbolType > & input, const automaton::RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > & nondeterministic, automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > >, ext::set < ext::pair < StateType, StateType > > > & deterministic, ext::map < ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > >, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > > > > & rubbishCallTransitions) { + const ext::set < ext::pair < StateType, StateType > > & S = unpackFromStateLabel(state); + + ext::set < StateType > R = retrieveDSubSet(S); + ext::set < StateType > R1; + + for(const StateType& q : R) { + for ( const auto & transition : nondeterministic.getCallTransitions()) { + if(q != transition.first.first) continue; + if(input != transition.first.second) continue; + + for(const auto& to : transition.second) { + const StateType& q1 = to.first; + + R1.insert(q1); + } + } + } + + bool R1Empty = R1.empty(); + auto to = packToStateLabel(createIdentity(std::move(R1))); + auto push = packToStackSymbolLabel(ext::make_pair(state, input)); + if(R1Empty) { + rubbishCallTransitions.insert(std::make_pair(ext::make_pair(state, input), ext::make_pair(to, push))); + } else { + addCallTransition(state, input, to, push, deterministic); + } +} + +template < class InputSymbolType, class EpsilonType, class StateType > +void addLocalTransition ( const ext::set < ext::pair < StateType, StateType > > & from, const ext::variant < EpsilonType, InputSymbolType > & input, const ext::set < ext::pair < StateType, StateType > > & to, automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > >, ext::set < ext::pair < StateType, StateType > > > & deterministic) { + deterministic.addState(from); + deterministic.addState(to); + + deterministic.addLocalTransition(from, input, to); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +void local(const ext::set < ext::pair < StateType, StateType > > & state, const ext::variant < EpsilonType, InputSymbolType > & input, const automaton::RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > & nondeterministic, automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > >, ext::set < ext::pair < StateType, StateType > > > & deterministic, ext::map < ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > >, ext::set < ext::pair < StateType, StateType > > > & rubbishLocalTransitions ) { + const ext::set<ext::pair<StateType, StateType>> & S = unpackFromStateLabel(state); + ext::set<ext::pair<StateType, StateType>> S1; + + for(const auto& entry : S) { + const StateType & q = entry.first; + const StateType & q2 = entry.second; + for(const auto& transition : nondeterministic.getLocalTransitions()) { + if(q2 != transition.first.first) continue; + if(input != transition.first.second) continue; + + for(const auto& to : transition.second) { + const StateType & q1 = to; + + S1.insert(ext::make_pair(q, q1)); + } + } + } + + bool S1Empty = S1.empty(); + auto to = packToStateLabel(std::move(S1)); + if(S1Empty) { + rubbishLocalTransitions.insert(std::make_pair(ext::make_pair(state, input), to)); + } else { + addLocalTransition(state, input, to, deterministic); + } +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +ext::tuple<ext::set<ext::variant<EpsilonType, InputSymbolType>>, ext::set<ext::variant<EpsilonType, InputSymbolType>>, ext::set<ext::variant<EpsilonType, InputSymbolType>>> getLocalCallRetPartitioning(const automaton::RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > & n, const ext::set < ext::pair < StateType, StateType > > & state) { + ext::set<ext::variant<EpsilonType, InputSymbolType>> local; + ext::set<ext::variant<EpsilonType, InputSymbolType>> call; + ext::set<ext::variant<EpsilonType, InputSymbolType>> ret; + + const ext::set<StateType> dSubSet = retrieveDSubSet(unpackFromStateLabel(state)); + + for(const auto& transition : n.getLocalTransitions()) { + if(dSubSet.count(transition.first.first)) + local.insert(transition.first.second); + } + + for(const auto& transition : n.getCallTransitions()) { + if(dSubSet.count(transition.first.first)) + call.insert(transition.first.second); + } + + for(const auto& transition : n.getReturnTransitions()) { + if(dSubSet.count(std::get<0>(transition.first))) + ret.insert(std::get<1>(transition.first)); + } + + return ext::make_tuple(std::move(local), std::move(call), std::move(ret)); +} + +template < class InputSymbolType, class EpsilonType, class PushdownStoreSymbolType, class StateType > +automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, ext::pair < ext::set < ext::pair < StateType, StateType > >, ext::variant < EpsilonType, InputSymbolType > >, ext::set < ext::pair < StateType, StateType > > > Determinize::determinize ( const automaton::RealTimeHeightDeterministicNPDA < InputSymbolType, EpsilonType, PushdownStoreSymbolType, StateType > & n ) { + using DeterministicStateType = ext::set < ext::pair < StateType, StateType > >; + using DeterministicPushdownStoreSymbolType = ext::pair < DeterministicStateType, ext::variant < EpsilonType, InputSymbolType > >; + + DeterministicStateType initialLabel = packToStateLabel(createIdentity(n.getInitialStates())); + DeterministicPushdownStoreSymbolType bottom = ext::make_pair ( DeterministicStateType { }, ext::variant < EpsilonType, InputSymbolType > ( alphabet::BottomOfTheStackSymbol::instance < InputSymbolType > ( ) ) ); + + automaton::RealTimeHeightDeterministicDPDA < InputSymbolType, EpsilonType, DeterministicPushdownStoreSymbolType, DeterministicStateType > d ( initialLabel, bottom ); + d.setInputAlphabet ( n.getInputAlphabet ( ) ); + + ext::set < DeterministicStateType > rubbishStates = { packToStateLabel < StateType > ({})}; + ext::map < ext::tuple < DeterministicStateType, ext::variant<EpsilonType, InputSymbolType>, DeterministicPushdownStoreSymbolType >, DeterministicStateType > rubbishReturnTransitions; + ext::map < ext::pair < DeterministicStateType, ext::variant<EpsilonType, InputSymbolType>>, ext::pair < DeterministicStateType, DeterministicPushdownStoreSymbolType > > rubbishCallTransitions; + ext::map < ext::pair < DeterministicStateType, ext::variant<EpsilonType, InputSymbolType>>, DeterministicStateType > rubbishLocalTransitions; + + for(;;) { + ext::set<ext::pair<DeterministicStateType, DeterministicPushdownStoreSymbolType>> stateSymbols = existsDirtyStateSymbol(d, rubbishStates, rubbishCallTransitions, rubbishReturnTransitions, n); + ext::set<DeterministicStateType> states = existsDirtyState(d, rubbishStates, rubbishCallTransitions, rubbishLocalTransitions, n); + + if(stateSymbols.empty() && states.empty()) break; + + for(const auto& stateSymbol : stateSymbols) { + if ( common::GlobalData::verbose ) + common::Streams::log << "Dirty state symbol: " << stateSymbol << std::endl; + + ext::tuple<ext::set<ext::variant<EpsilonType, InputSymbolType>>, ext::set<ext::variant<EpsilonType, InputSymbolType>>, ext::set<ext::variant<EpsilonType, InputSymbolType>>> partitioning = getLocalCallRetPartitioning(n, stateSymbol.first); + + ext::set<ext::variant<EpsilonType, InputSymbolType>>& retPart = std::get<2>(partitioning); + + for(const auto& symbol : retPart) { + if(stateSymbol.second == d.getBottomOfTheStackSymbol()) { + retInitial(stateSymbol.first, stateSymbol.second, symbol, n, d, rubbishReturnTransitions); + } else { + ret(stateSymbol.first, stateSymbol.second, symbol, n, d, rubbishReturnTransitions); + } + } + } + + for(const auto& state : states) { + if ( common::GlobalData::verbose ) + common::Streams::log << "Dirty state: " << state << std::endl; + ext::tuple<ext::set<ext::variant<EpsilonType, InputSymbolType>>, ext::set<ext::variant<EpsilonType, InputSymbolType>>, ext::set<ext::variant<EpsilonType, InputSymbolType>>> partitioning = getLocalCallRetPartitioning(n, state); + + ext::set<ext::variant<EpsilonType, InputSymbolType>>& localPart = std::get<0>(partitioning); + ext::set<ext::variant<EpsilonType, InputSymbolType>>& callPart = std::get<1>(partitioning); + + for(const auto& symbol : localPart) { + local(state, symbol, n, d, rubbishLocalTransitions); + } + for(const auto& symbol : callPart) { + call(state, symbol, n, d, rubbishCallTransitions); + } + } + } + + const ext::set<StateType>& finalLabels = n.getFinalStates(); + for(const DeterministicStateType & state : d.getStates()) { + const ext::set<StateType> labels = retrieveDSubSet(unpackFromStateLabel(state)); + + if(!ext::excludes(finalLabels.begin(), finalLabels.end(), labels.begin(), labels.end())) { + d.addFinalState(state); + } + } + + if ( common::GlobalData::verbose ) { + common::Streams::log << "Rubbish states: " << rubbishStates << std::endl; + common::Streams::log << "Rubbish return transitions: " << rubbishReturnTransitions << std::endl; + common::Streams::log << "Rubbish call transitions: " << rubbishCallTransitions << std::endl; + common::Streams::log << "Rubbish local transitions:" << rubbishLocalTransitions << std::endl; + } + + return d; +} + +} /* namespace determinize */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx b/alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx deleted file mode 100644 index 98693d817b560a1267e5a303187dfa1223438ea9..0000000000000000000000000000000000000000 --- a/alib2algo/src/automaton/determinize/DeterminizeVPAPart.cxx +++ /dev/null @@ -1,212 +0,0 @@ -/* - * NFADeterminizer.cpp - * - * Created on: 16. 1. 2014 - * Author: Jan Travnicek - */ - -#include "common/RHDPDACommon.h" - -#include <automaton/PDA/VisiblyPushdownNPDA.h> -#include <alib/set> - -namespace automaton { - -namespace determinize { - -void addRetTransition(const DefaultStateType& from, const DefaultSymbolType& input, const DefaultSymbolType& dvpdaSymbol, const DefaultStateType& to, automaton::VisiblyPushdownDPDA < > & deterministic) { - deterministic.addState(from); - deterministic.addState(to); - deterministic.addPushdownStoreSymbol(dvpdaSymbol); - - deterministic.addReturnTransition(from, input, dvpdaSymbol, to); -} - -void retInitial(const DefaultStateType& state, const DefaultSymbolType& pdaSymbol, const DefaultSymbolType& input, const automaton::VisiblyPushdownNPDA < > & nondeterministic, automaton::VisiblyPushdownDPDA < > & deterministic) { - const ext::set<ext::pair<DefaultStateType, DefaultStateType>> & S = unpackFromStateLabel(state); - - ext::set<ext::pair<DefaultStateType, DefaultStateType>> S1; - for(const auto& entry : S) { - const DefaultStateType& q = entry.first; - const DefaultStateType& q2 = entry.second; - - for(const auto& transition : nondeterministic.getReturnTransitions()) { - if(q2 != std::get<0>(transition.first)) continue; - if(input != std::get<1>(transition.first)) continue; - if(nondeterministic.getBottomOfTheStackSymbol() != std::get<2>(transition.first)) continue; - - for(const auto& to : transition.second) { - const DefaultStateType& q1 = to; - S1.insert(ext::make_pair(q, q1)); - } - } - } - - addRetTransition(state, input, pdaSymbol, DefaultStateType(packToStateLabel(std::move(S1))), deterministic); -} - -void ret(const DefaultStateType& state, const DefaultSymbolType& pdaSymbol, const DefaultSymbolType& input, const automaton::VisiblyPushdownNPDA < > & nondeterministic, automaton::VisiblyPushdownDPDA < > & deterministic) { - const ext::set<ext::pair<DefaultStateType, DefaultStateType>> & S = unpackFromStateLabel(state); - const ext::pair<DefaultStateType, DefaultSymbolType> & pdaSymbolUnpack = unpackFromDVPAStackSymbol(pdaSymbol); - const ext::set<ext::pair<DefaultStateType, DefaultStateType>>& S1 = unpackFromStateLabel ( pdaSymbolUnpack.first ); - - ext::set<ext::pair<DefaultStateType, DefaultStateType>> update; - - for(const auto& transition : nondeterministic.getCallTransitions()) { - if(pdaSymbolUnpack.second != std::get<1>(transition.first)) continue; - - const DefaultStateType& q = std::get<0>(transition.first); - for(const auto& to : transition.second) { - const DefaultStateType& q1 = to.first; - const DefaultSymbolType& gamma = to.second; - - for(const auto& entry : S) { - if(q1 != entry.first) continue; - const DefaultStateType& q2 = entry.second; - - for(const auto& transition2 : nondeterministic.getReturnTransitions()) { - if(q2 != std::get<0>(transition2.first)) continue; - if(input != std::get<1>(transition2.first)) continue; - if(gamma != std::get<2>(transition2.first)) continue; - - for(const auto& to2 : transition2.second) { - const DefaultStateType& qI = to2; - - update.insert(ext::make_pair(q, qI)); - } - } - } - } - } - - ext::set<ext::pair<DefaultStateType, DefaultStateType>> S2; - for(const auto& entry : S1) { - const DefaultStateType& q = entry.first; - const DefaultStateType& q3 = entry.second; - for(const auto& entry2 : update) { - if(q3 != entry2.first) continue; - - const DefaultStateType& qI = entry2.second; - - S2.insert(ext::make_pair(q, qI)); - } - } - - addRetTransition(state, input, pdaSymbol, DefaultStateType(packToStateLabel(std::move(S2))), deterministic); -} - -void addCallTransition(const DefaultStateType& from, const DefaultSymbolType& input, const DefaultStateType& to, const DefaultSymbolType& dvpdaSymbol, automaton::VisiblyPushdownDPDA < > & deterministic) { - deterministic.addState(from); - deterministic.addState(to); - deterministic.addPushdownStoreSymbol(dvpdaSymbol); - - deterministic.addCallTransition(from, input, to, dvpdaSymbol); -} - -void call(const DefaultStateType& state, const DefaultSymbolType& input, const automaton::VisiblyPushdownNPDA < > & nondeterministic, automaton::VisiblyPushdownDPDA < > & deterministic) { - const ext::set<ext::pair<DefaultStateType, DefaultStateType>> & S = unpackFromStateLabel(state); - - ext::set<DefaultStateType> R = retrieveDSubSet(S); - ext::set<DefaultStateType> R1; - - for(const DefaultStateType& q : R) { - for(const auto& transition : nondeterministic.getCallTransitions()) { - if(q != transition.first.first) continue; - if(input != transition.first.second) continue; - - for(const auto& to : transition.second) { - const DefaultStateType& q1 = to.first; - - R1.insert(q1); - } - } - } - - addCallTransition(state, input, DefaultStateType(packToStateLabel(createIdentity(std::move(R1)))), packToStackSymbolLabel(ext::make_pair(state, input)), deterministic); -} - -void addLocalTransition(const DefaultStateType& from, const DefaultSymbolType& input, const DefaultStateType& to, automaton::VisiblyPushdownDPDA < > & deterministic) { - deterministic.addState(from); - deterministic.addState(to); - - deterministic.addLocalTransition(from, input, to); -} - -void local(const DefaultStateType& state, const DefaultSymbolType& input, const automaton::VisiblyPushdownNPDA < > & nondeterministic, automaton::VisiblyPushdownDPDA < > & deterministic) { - const ext::set<ext::pair<DefaultStateType, DefaultStateType>> & S = unpackFromStateLabel(state); - ext::set<ext::pair<DefaultStateType, DefaultStateType>> S1; - - for(const auto& entry : S) { - const DefaultStateType & q = entry.first; - const DefaultStateType & q2 = entry.second; - for(const auto& transition : nondeterministic.getLocalTransitions()) { - if(q2 != transition.first.first) continue; - if(input != transition.first.second) continue; - - for(const auto& to : transition.second) { - const DefaultStateType & q1 = to; - - S1.insert(ext::make_pair(q, q1)); - } - } - } - - addLocalTransition(state, input, DefaultStateType(packToStateLabel(std::move(S1))), deterministic); -} - -automaton::VisiblyPushdownDPDA < > Determinize::determinize(const automaton::VisiblyPushdownNPDA < > & n) { - DefaultStateType initialLabel = packToStateLabel(createIdentity(n.getInitialStates())); - - automaton::VisiblyPushdownDPDA < > d(initialLabel, n.getBottomOfTheStackSymbol()); - d.setCallInputAlphabet(n.getCallInputAlphabet()); - d.setLocalInputAlphabet(n.getLocalInputAlphabet()); - d.setReturnInputAlphabet(n.getReturnInputAlphabet()); - - ext::set<DefaultStateType> rubbishStates = {DefaultStateType(packToStateLabel({}))}; - ext::map<ext::tuple<DefaultStateType, DefaultSymbolType, DefaultSymbolType>, DefaultStateType> rubbishReturnTransitions; - ext::map<ext::pair<DefaultStateType, DefaultSymbolType>, ext::pair<DefaultStateType, DefaultSymbolType> > rubbishCallTransitions; - ext::map<ext::pair<DefaultStateType, DefaultSymbolType>, DefaultStateType> rubbishLocalTransitions; - - for(;;) { - ext::set<ext::pair<DefaultStateType, DefaultSymbolType>> stateSymbols = existsDirtyStateSymbol(d, rubbishStates, rubbishCallTransitions, rubbishReturnTransitions, n); - ext::set<DefaultStateType> states = existsDirtyState(d, rubbishStates, rubbishCallTransitions, rubbishLocalTransitions, n); - - if(stateSymbols.empty() && states.empty()) break; - - for(const auto& stateSymbol: stateSymbols) { - for(const DefaultSymbolType& symbol : n.getReturnInputAlphabet()) { - if(stateSymbol.second == d.getBottomOfTheStackSymbol()) { - retInitial(stateSymbol.first, stateSymbol.second, symbol, n, d); - } else { - ret(stateSymbol.first, stateSymbol.second, symbol, n, d); - } - } - } - - for(const auto& state : states) { - for(const DefaultSymbolType& symbol : n.getLocalInputAlphabet()) { - local(state, symbol, n, d); - } - for(const DefaultSymbolType& symbol : n.getCallInputAlphabet()) { - call(state, symbol, n, d); - } - } - } - - const ext::set<DefaultStateType>& finalLabels = n.getFinalStates(); - for(const DefaultStateType& state : d.getStates()) { - const ext::set<DefaultStateType> labels = retrieveDSubSet(unpackFromStateLabel(state)); - - if(!ext::excludes(finalLabels.begin(), finalLabels.end(), labels.begin(), labels.end())) { - d.addFinalState(state); - } - } - - return d; -} - -auto DeterminizeVisiblyPushdownNPDA = registration::AbstractRegister < Determinize, automaton::VisiblyPushdownDPDA < >, const automaton::VisiblyPushdownNPDA < > & > ( Determinize::determinize ); - -} /* namespace determinize */ - -} /* namespace automaton */ diff --git a/alib2algo/src/automaton/determinize/DeterminizeVPAPart.hxx b/alib2algo/src/automaton/determinize/DeterminizeVPAPart.hxx new file mode 100644 index 0000000000000000000000000000000000000000..88754c76bc59ed9d921d0a665e42c511af1a88a5 --- /dev/null +++ b/alib2algo/src/automaton/determinize/DeterminizeVPAPart.hxx @@ -0,0 +1,224 @@ +/* + * NFADeterminizer.cpp + * + * Created on: 16. 1. 2014 + * Author: Jan Travnicek + */ + +#include "common/RHDPDACommon.h" + +#include <alphabet/BottomOfTheStackSymbol.h> +#include <automaton/PDA/VisiblyPushdownNPDA.h> +#include <alib/set> + +namespace automaton { + +namespace determinize { + +template < class InputSymbolType, class StateType > +void addRetTransition(const ext::set < ext::pair < StateType, StateType > > & from, const InputSymbolType& input, const ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType > & dvpdaSymbol, const ext::set < ext::pair < StateType, StateType > > & to, automaton::VisiblyPushdownDPDA < InputSymbolType, ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType >, ext::set < ext::pair < StateType, StateType > > > & deterministic) { + deterministic.addState(from); + deterministic.addState(to); + deterministic.addPushdownStoreSymbol(dvpdaSymbol); + + deterministic.addReturnTransition(from, input, dvpdaSymbol, to); +} + +template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > +void retInitial ( const ext::set < ext::pair < StateType, StateType > > & state, const ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType > & pdaSymbol, const InputSymbolType & input, const automaton::VisiblyPushdownNPDA < InputSymbolType, PushdownStoreSymbolType, StateType > & nondeterministic, automaton::VisiblyPushdownDPDA < InputSymbolType, ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType >, ext::set < ext::pair < StateType, StateType > > > & deterministic) { + const ext::set<ext::pair<StateType, StateType>> & S = unpackFromStateLabel(state); + + ext::set<ext::pair<StateType, StateType>> S1; + for(const auto& entry : S) { + const StateType& q = entry.first; + const StateType& q2 = entry.second; + + for(const auto& transition : nondeterministic.getReturnTransitions()) { + if(q2 != std::get<0>(transition.first)) continue; + if(input != std::get<1>(transition.first)) continue; + if(nondeterministic.getBottomOfTheStackSymbol() != std::get<2>(transition.first)) continue; + + for(const auto& to : transition.second) { + const StateType& q1 = to; + S1.insert(ext::make_pair(q, q1)); + } + } + } + + addRetTransition(state, input, pdaSymbol, packToStateLabel(std::move(S1)), deterministic); +} + +template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > +void ret(const ext::set < ext::pair < StateType, StateType > > & state, const ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType > & pdaSymbol, const InputSymbolType & input, const automaton::VisiblyPushdownNPDA < InputSymbolType, PushdownStoreSymbolType, StateType > & nondeterministic, automaton::VisiblyPushdownDPDA < InputSymbolType, ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType >, ext::set < ext::pair < StateType, StateType > > > & deterministic) { + const ext::set<ext::pair<StateType, StateType>> & S = unpackFromStateLabel(state); + const ext::pair<ext::set<ext::pair<StateType, StateType>>, InputSymbolType> & pdaSymbolUnpack = unpackFromStackSymbol(pdaSymbol); + const ext::set<ext::pair<StateType, StateType>>& S1 = unpackFromStateLabel ( pdaSymbolUnpack.first ); + + ext::set<ext::pair<StateType, StateType>> update; + + for(const auto& transition : nondeterministic.getCallTransitions()) { + if(pdaSymbolUnpack.second != std::get<1>(transition.first)) continue; + + const StateType& q = std::get<0>(transition.first); + for(const auto& to : transition.second) { + const StateType& q1 = to.first; + const PushdownStoreSymbolType& gamma = to.second; + + for(const auto& entry : S) { + if(q1 != entry.first) continue; + const StateType& q2 = entry.second; + + for(const auto& transition2 : nondeterministic.getReturnTransitions()) { + if(q2 != std::get<0>(transition2.first)) continue; + if(input != std::get<1>(transition2.first)) continue; + if(gamma != std::get<2>(transition2.first)) continue; + + for(const auto& to2 : transition2.second) { + const StateType& qI = to2; + + update.insert(ext::make_pair(q, qI)); + } + } + } + } + } + + ext::set<ext::pair<StateType, StateType>> S2; + for(const auto& entry : S1) { + const StateType& q = entry.first; + const StateType& q3 = entry.second; + for(const auto& entry2 : update) { + if(q3 != entry2.first) continue; + + const StateType& qI = entry2.second; + + S2.insert(ext::make_pair(q, qI)); + } + } + + addRetTransition(state, input, pdaSymbol, packToStateLabel(std::move(S2)), deterministic); +} + +template < class InputSymbolType, class StateType > +void addCallTransition(const ext::set < ext::pair < StateType, StateType > > & from, const InputSymbolType& input, const ext::set < ext::pair < StateType, StateType > >& to, const ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType > & dvpdaSymbol, automaton::VisiblyPushdownDPDA < InputSymbolType, ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType >, ext::set < ext::pair < StateType, StateType > > > & deterministic) { + deterministic.addState(from); + deterministic.addState(to); + deterministic.addPushdownStoreSymbol(dvpdaSymbol); + + deterministic.addCallTransition(from, input, to, dvpdaSymbol); +} + +template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > +void call(const ext::set < ext::pair < StateType, StateType > > & state, const InputSymbolType& input, const automaton::VisiblyPushdownNPDA < InputSymbolType, PushdownStoreSymbolType, StateType > & nondeterministic, automaton::VisiblyPushdownDPDA < InputSymbolType, ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType >, ext::set < ext::pair < StateType, StateType > > > & deterministic) { + const ext::set<ext::pair<StateType, StateType>> & S = unpackFromStateLabel(state); + + ext::set<StateType> R = retrieveDSubSet(S); + ext::set<StateType> R1; + + for(const StateType& q : R) { + for(const auto& transition : nondeterministic.getCallTransitions()) { + if(q != transition.first.first) continue; + if(input != transition.first.second) continue; + + for(const auto& to : transition.second) { + const StateType& q1 = to.first; + + R1.insert(q1); + } + } + } + + addCallTransition(state, input, packToStateLabel(createIdentity(std::move(R1))), packToStackSymbolLabel(ext::make_pair(state, input)), deterministic); +} + +template < class InputSymbolType, class StateType > +void addLocalTransition(const ext::set < ext::pair < StateType, StateType > > & from, const InputSymbolType & input, const ext::set < ext::pair < StateType, StateType > > & to, automaton::VisiblyPushdownDPDA < InputSymbolType, ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType >, ext::set < ext::pair < StateType, StateType > > > & deterministic) { + deterministic.addState(from); + deterministic.addState(to); + + deterministic.addLocalTransition(from, input, to); +} + +template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > +void local(const ext::set < ext::pair < StateType, StateType > > & state, const InputSymbolType& input, const automaton::VisiblyPushdownNPDA < InputSymbolType, PushdownStoreSymbolType, StateType > & nondeterministic, automaton::VisiblyPushdownDPDA < InputSymbolType, ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType >, ext::set < ext::pair < StateType, StateType > > > & deterministic) { + const ext::set<ext::pair<StateType, StateType>> & S = unpackFromStateLabel(state); + ext::set<ext::pair<StateType, StateType>> S1; + + for(const auto& entry : S) { + const StateType & q = entry.first; + const StateType & q2 = entry.second; + for(const auto& transition : nondeterministic.getLocalTransitions()) { + if(q2 != transition.first.first) continue; + if(input != transition.first.second) continue; + + for(const auto& to : transition.second) { + const StateType & q1 = to; + + S1.insert(ext::make_pair(q, q1)); + } + } + } + + addLocalTransition(state, input, packToStateLabel(std::move(S1)), deterministic); +} + +template < class InputSymbolType, class PushdownStoreSymbolType, class StateType > +automaton::VisiblyPushdownDPDA < InputSymbolType, ext::pair < ext::set < ext::pair < StateType, StateType > >, InputSymbolType >, ext::set < ext::pair < StateType, StateType > > > Determinize::determinize ( const automaton::VisiblyPushdownNPDA < InputSymbolType, PushdownStoreSymbolType, StateType > & n ) { + using DeterministicStateType = ext::set < ext::pair < StateType, StateType > >; + using DeterministicPushdownStoreSymbolType = ext::pair < DeterministicStateType, InputSymbolType >; + + DeterministicStateType initialLabel = packToStateLabel(createIdentity(n.getInitialStates())); + DeterministicPushdownStoreSymbolType bottom = ext::make_pair ( DeterministicStateType { }, alphabet::BottomOfTheStackSymbol::instance < InputSymbolType > ( ) ); + + automaton::VisiblyPushdownDPDA < InputSymbolType, DeterministicPushdownStoreSymbolType, DeterministicStateType > d(initialLabel, bottom); + + d.setCallInputAlphabet(n.getCallInputAlphabet()); + d.setLocalInputAlphabet(n.getLocalInputAlphabet()); + d.setReturnInputAlphabet(n.getReturnInputAlphabet()); + + ext::set < DeterministicStateType > rubbishStates = { packToStateLabel < StateType > ({})}; + ext::map < ext::tuple < DeterministicStateType, InputSymbolType, DeterministicPushdownStoreSymbolType >, DeterministicStateType > rubbishReturnTransitions; + ext::map < ext::pair < DeterministicStateType, InputSymbolType>, ext::pair < DeterministicStateType, DeterministicPushdownStoreSymbolType > > rubbishCallTransitions; + ext::map < ext::pair < DeterministicStateType, InputSymbolType>, DeterministicStateType > rubbishLocalTransitions; + + for(;;) { + ext::set<ext::pair<DeterministicStateType, DeterministicPushdownStoreSymbolType>> stateSymbols = existsDirtyStateSymbol(d, rubbishStates, rubbishCallTransitions, rubbishReturnTransitions, n); + ext::set<DeterministicStateType> states = existsDirtyState(d, rubbishStates, rubbishCallTransitions, rubbishLocalTransitions, n); + + if(stateSymbols.empty() && states.empty()) break; + + for(const auto& stateSymbol: stateSymbols) { + for(const InputSymbolType& symbol : n.getReturnInputAlphabet()) { + if(stateSymbol.second == d.getBottomOfTheStackSymbol()) { + retInitial(stateSymbol.first, stateSymbol.second, symbol, n, d); + } else { + ret(stateSymbol.first, stateSymbol.second, symbol, n, d); + } + } + } + + for(const auto& state : states) { + for(const InputSymbolType& symbol : n.getLocalInputAlphabet()) { + local(state, symbol, n, d); + } + for(const InputSymbolType& symbol : n.getCallInputAlphabet()) { + call(state, symbol, n, d); + } + } + } + + const ext::set<StateType>& finalLabels = n.getFinalStates(); + for(const DeterministicStateType & state : d.getStates()) { + const ext::set<StateType> labels = retrieveDSubSet(unpackFromStateLabel(state)); + + if(!ext::excludes(finalLabels.begin(), finalLabels.end(), labels.begin(), labels.end())) { + d.addFinalState(state); + } + } + + return d; +} + +} /* namespace determinize */ + +} /* namespace automaton */ diff --git a/alib2algo/src/automaton/determinize/common/RHDPDACommon.cpp b/alib2algo/src/automaton/determinize/common/RHDPDACommon.cpp deleted file mode 100644 index 3d6743e24bf3faf7d6e5f71c0590d219c22657a7..0000000000000000000000000000000000000000 --- a/alib2algo/src/automaton/determinize/common/RHDPDACommon.cpp +++ /dev/null @@ -1,230 +0,0 @@ -#include "RHDPDACommon.h" -#include "object/AnyObject.h" -#include "object/Object.h" - -#include "automaton/PDA/VisiblyPushdownNPDA.h" -#include "automaton/PDA/RealTimeHeightDeterministicNPDA.h" - -namespace automaton { - -namespace determinize { - -DefaultStateType packToStateLabel(ext::set<ext::pair<DefaultStateType, DefaultStateType>>&& data) { - return DefaultStateType ( object::AnyObject < ext::set<ext::pair<DefaultStateType, DefaultStateType>> > ( std::move ( data ) ) ); -} - -const ext::set<ext::pair<DefaultStateType, DefaultStateType>> & unpackFromStateLabel(const DefaultStateType& data) { - return static_cast < const object::AnyObject < ext::set<ext::pair<DefaultStateType, DefaultStateType>> > & > ( data.getData ( ) ).getData ( ); -} - -DefaultSymbolType packToStackSymbolLabel(ext::pair<DefaultStateType, DefaultSymbolType>&& data) { - return DefaultSymbolType ( object::AnyObject < ext::pair<DefaultStateType, DefaultSymbolType> > ( std::move ( data ) ) ); -} - -const ext::pair<DefaultStateType, DefaultSymbolType> & unpackFromDVPAStackSymbol(const DefaultSymbolType& symbol) { - return static_cast < const object::AnyObject < ext::pair<DefaultStateType, DefaultSymbolType> > & > ( symbol.getData ( ) ).getData ( ); -} - -DefaultSymbolType packToStackSymbolLabel(ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>>&& data) { - return DefaultSymbolType ( object::AnyObject < ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>> > ( std::move ( data ) ) ); -} - -const ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>> & unpackFromDRHDPDAStackSymbol(const DefaultSymbolType& symbol) { - return static_cast < const object::AnyObject < ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>> > & > ( symbol.getData ( ) ).getData ( ); -} - -ext::set<DefaultStateType> retrieveDSubSet(const ext::set<ext::pair<DefaultStateType, DefaultStateType>>& localOperation) { - ext::set<DefaultStateType> id; - for(const auto& entry : localOperation) { - id.insert(entry.second); - } - return id; -} - -ext::set<ext::pair<DefaultStateType, DefaultStateType>> createIdentity(const ext::set<DefaultStateType>& states) { - ext::set<ext::pair<DefaultStateType, DefaultStateType>> id; - for(const DefaultStateType& state : states) { - id.insert(ext::make_pair(state, state)); - } - return id; -} - -template<class T, class S, class R> -ext::set<DefaultStateType> existsDirtyState(const T& d, const ext::set<DefaultStateType>& rubbishStates, const ext::map<ext::pair<DefaultStateType, S>, ext::pair<DefaultStateType, DefaultSymbolType> >& rubbishCallTransitions, const ext::map<ext::pair<DefaultStateType, S>, DefaultStateType>& rubbishLocalTransitions, const R& n) { - ext::set<DefaultStateType> dirtyStates; - - ext::set<DefaultStateType> states = d.getStates(); - states.insert(rubbishStates.begin(), rubbishStates.end()); - - auto callTransitions = d.getCallTransitions(); - callTransitions.insert(rubbishCallTransitions.begin(), rubbishCallTransitions.end()); - - auto localTransitions = d.getLocalTransitions(); - localTransitions.insert(rubbishLocalTransitions.begin(), rubbishLocalTransitions.end()); - - for(const DefaultStateType& state : states) { - const ext::set<DefaultStateType> dSubSet = retrieveDSubSet(unpackFromStateLabel(state)); - - bool originalCallsLocals = false; - for(const auto& transition : n.getCallTransitions()) { - if(dSubSet.count(transition.first.first)) { - originalCallsLocals = true; - break; - } - } - if(!originalCallsLocals) for(const auto& transition : n.getLocalTransitions()) { - if(dSubSet.count(transition.first.first)) { - originalCallsLocals = true; - break; - } - } - - if(!originalCallsLocals) continue; - bool deterministicCallLocals = false; - - for(const auto& transition : callTransitions) { - if(state == transition.first.first) { - deterministicCallLocals = true; - break; - } - } - if(deterministicCallLocals) for(const auto& transition : localTransitions) { - if(state == transition.first.first) { - deterministicCallLocals = true; - break; - } - } - - if(originalCallsLocals && !deterministicCallLocals) dirtyStates.insert(state); - - } - return dirtyStates; -} - -template ext::set<DefaultStateType> existsDirtyState(const automaton::VisiblyPushdownDPDA < > & d, const ext::set<DefaultStateType>& rubbishStates, const ext::map<ext::pair<DefaultStateType, DefaultSymbolType>, ext::pair<DefaultStateType, DefaultSymbolType> >& rubbishCallTransitions, const ext::map<ext::pair<DefaultStateType, DefaultSymbolType>, DefaultStateType>& rubbishLocalTransitions, const automaton::VisiblyPushdownNPDA < > & n); -template ext::set<DefaultStateType> existsDirtyState(const automaton::RealTimeHeightDeterministicDPDA < > & d, const ext::set<DefaultStateType>& rubbishStates, const ext::map<ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>>, ext::pair<DefaultStateType, DefaultSymbolType> >& rubbishCallTransitions, const ext::map<ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>>, DefaultStateType>& rubbishLocalTransitions, const automaton::RealTimeHeightDeterministicNPDA < > & n); - -void localClosure(ext::set<DefaultStateType>& states, const ext::set<DefaultStateType>& oldStates, const automaton::RealTimeHeightDeterministicDPDA < > & d) { - ext::set<DefaultStateType> newStates; - - for(const DefaultStateType& state : oldStates) { - for(const auto& transition : d.getLocalTransitions()) { - if(transition.second != state) continue; - - if(!states.count(transition.first.first)) { - states.insert(transition.first.first); - newStates.insert(transition.first.first); - } - } - - for(const auto& transition : d.getReturnTransitions()) { - if(transition.second != state) continue; - - const DefaultSymbolType& popSymbol = std::get<2>(transition.first); - if(popSymbol == d.getBottomOfTheStackSymbol()) continue; - - const DefaultStateType & statePart = unpackFromDRHDPDAStackSymbol ( popSymbol ).first; - - if(!states.count(statePart)) { - states.insert(statePart); - newStates.insert(statePart); - } - } - } - - if(newStates.empty()) return; - localClosure(states, newStates, d); -} - -void localClosure(ext::set<DefaultStateType>& states, const ext::set<DefaultStateType>& oldStates, const VisiblyPushdownDPDA < > & d) { - ext::set<DefaultStateType> newStates; - - for(const DefaultStateType& state : oldStates) { - for(const auto& transition : d.getLocalTransitions()) { - if(transition.second != state) continue; - - if(!states.count(transition.first.first)) { - states.insert(transition.first.first); - newStates.insert(transition.first.first); - } - } - - for(const auto& transition : d.getReturnTransitions()) { - if(transition.second != state) continue; - - const DefaultSymbolType& popSymbol = std::get<2>(transition.first); - if(popSymbol == d.getBottomOfTheStackSymbol()) continue; - - const DefaultStateType & statePart = unpackFromDVPAStackSymbol ( popSymbol ).first; - - if(!states.count(statePart)) { - states.insert(statePart); - newStates.insert(statePart); - } - } - } - - if(newStates.empty()) return; - localClosure(states, newStates, d); -} - -template<class T, class S, class R> -ext::set<ext::pair<DefaultStateType, DefaultSymbolType>> existsDirtyStateSymbol(const T& d, const ext::set<DefaultStateType>& rubbishStates, const ext::map<ext::pair<DefaultStateType, S>, ext::pair<DefaultStateType, DefaultSymbolType> >& rubbishCallTransitions, const ext::map<ext::tuple<DefaultStateType, S, DefaultSymbolType>, DefaultStateType>& rubbishReturnTransitions, const R& n) { - ext::set<ext::pair<DefaultStateType, DefaultSymbolType>> dirtyStateSymbols; - - ext::set<DefaultStateType> states = d.getStates(); - states.insert(rubbishStates.begin(), rubbishStates.end()); - - auto callTransitions = d.getCallTransitions(); - callTransitions.insert(rubbishCallTransitions.begin(), rubbishCallTransitions.end()); - - auto returnTransitions = d.getReturnTransitions(); - returnTransitions.insert(rubbishReturnTransitions.begin(), rubbishReturnTransitions.end()); - - for(const DefaultStateType& state : states) { - bool originalPops = false; - const ext::set<DefaultStateType> dSubSet = retrieveDSubSet(unpackFromStateLabel(state)); - - for(const auto& transition : n.getReturnTransitions()) { - if(dSubSet.count(std::get<0>(transition.first))) { - originalPops = true; - break; - } - } - if(!originalPops) continue; - - ext::set<DefaultStateType> lc { state }; - localClosure(lc, ext::set<DefaultStateType>{state}, d); //intentional copy - - ext::set<DefaultSymbolType> topSymbols; - for(const DefaultStateType& localState : lc) { - for(const auto& transition : callTransitions) { - const auto& to = transition.second; - if(localState != to.first) continue; - - topSymbols.insert(to.second); - } - - if(d.getInitialState() == localState) { - topSymbols.insert(d.getBottomOfTheStackSymbol()); - } - } - - for(const auto& transition : returnTransitions) { - if(state != std::get<0>(transition.first)) continue; - - topSymbols.erase(std::get<2>(transition.first)); - } - - for(const DefaultSymbolType& topSymbol : topSymbols) - dirtyStateSymbols.insert(ext::make_pair(state, topSymbol)); - } - return dirtyStateSymbols; -} - -template ext::set<ext::pair<DefaultStateType, DefaultSymbolType>> existsDirtyStateSymbol(const automaton::VisiblyPushdownDPDA < > & d, const ext::set<DefaultStateType>& rubbishStates, const ext::map<ext::pair<DefaultStateType, DefaultSymbolType>, ext::pair<DefaultStateType, DefaultSymbolType> >& rubbishCallTransitions, const ext::map<ext::tuple<DefaultStateType, DefaultSymbolType, DefaultSymbolType>, DefaultStateType>& rubbishReturnTransitions, const automaton::VisiblyPushdownNPDA < > & n); -template ext::set<ext::pair<DefaultStateType, DefaultSymbolType>> existsDirtyStateSymbol(const automaton::RealTimeHeightDeterministicDPDA < > & d, const ext::set<DefaultStateType>& rubbishStates, const ext::map<ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>>, ext::pair<DefaultStateType, DefaultSymbolType> >& rubbishCallTransitions, const ext::map<ext::tuple<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>, DefaultSymbolType>, DefaultStateType>& rubbishReturnTransitions, const automaton::RealTimeHeightDeterministicNPDA < > & n); - -} /* namespace automaton */ - -} /* namespace determinize */ diff --git a/alib2algo/src/automaton/determinize/common/RHDPDACommon.h b/alib2algo/src/automaton/determinize/common/RHDPDACommon.h index bf8bf354c4e02a4c6111e18279fcfb1d9b1ca85b..b2f3a6d920934a795b09bb6ef3c483c764e25ece 100644 --- a/alib2algo/src/automaton/determinize/common/RHDPDACommon.h +++ b/alib2algo/src/automaton/determinize/common/RHDPDACommon.h @@ -14,30 +14,193 @@ namespace automaton { namespace determinize { -DefaultStateType packToStateLabel(ext::set<ext::pair<DefaultStateType, DefaultStateType>>&& data); +template < class StateType > +ext::set<ext::pair<StateType, StateType>> packToStateLabel(ext::set<ext::pair<StateType, StateType>> data) { + return std::move ( data ); +} + +template < class StateType > +const ext::set<ext::pair<StateType, StateType>> & unpackFromStateLabel(const ext::set<ext::pair<StateType, StateType>> & data) { + return data; +} + +template < class StateType, class InputSymbolType > +ext::pair<ext::set<ext::pair<StateType, StateType>>, InputSymbolType> packToStackSymbolLabel(ext::pair<ext::set<ext::pair<StateType, StateType>>, InputSymbolType> data) { + return std::move ( data ); +} + +template < class StateType, class InputSymbolType > +const ext::pair<ext::set<ext::pair<StateType, StateType>>, InputSymbolType> & unpackFromStackSymbol(const ext::pair<ext::set<ext::pair<StateType, StateType>>, InputSymbolType> & symbol) { + return symbol; +} + +template < class StateType, class EpsilonType, class InputSymbolType > +ext::pair<ext::set<ext::pair<StateType, StateType>>, ext::variant<EpsilonType, InputSymbolType>> packToStackSymbolLabel(ext::pair<ext::set<ext::pair<StateType, StateType>>, ext::variant<EpsilonType, InputSymbolType>> data) { + return std::move ( data ); +} + +template < class StateType, class EpsilonType, class InputSymbolType > +const ext::pair<ext::set<ext::pair<StateType, StateType>>, ext::variant<EpsilonType, InputSymbolType>> & unpackFromStackSymbol(const ext::pair<ext::set<ext::pair<StateType, StateType>>, ext::variant<EpsilonType, InputSymbolType>> & symbol) { + return symbol; +} + +template < class StateType > +ext::set<StateType> retrieveDSubSet(const ext::set<ext::pair<StateType, StateType>>& localOperation) { + ext::set<StateType> id; + for(const ext::pair < StateType, StateType > & entry : localOperation) { + id.insert(entry.second); + } + return id; +} + +template < class StateType > +ext::set<ext::pair<StateType, StateType>> createIdentity(const ext::set<StateType>& states) { + ext::set<ext::pair<StateType, StateType>> id; + for(const StateType& state : states) { + id.insert(ext::make_pair(state, state)); + } + return id; +} + +template<class T, class StateType, class InputSymbolType, class DeterministicPushdownStoreSymbolType, class R> +ext::set<ext::set<ext::pair<StateType,StateType>>> existsDirtyState(const T& d, const ext::set<ext::set<ext::pair<StateType,StateType>>>& rubbishStates, const ext::map<ext::pair< ext::set<ext::pair<StateType, StateType>>, InputSymbolType>, DeterministicPushdownStoreSymbolType >& rubbishCallTransitions, const ext::map<ext::pair<ext::set<ext::pair<StateType,StateType>>, InputSymbolType>, ext::set<ext::pair<StateType,StateType>>>& rubbishLocalTransitions, const R& n) { + ext::set<ext::set<ext::pair<StateType,StateType>>> dirtyStates; + + ext::set<ext::set<ext::pair<StateType,StateType>>> states = d.getStates(); + states.insert(rubbishStates.begin(), rubbishStates.end()); + + auto callTransitions = d.getCallTransitions(); + callTransitions.insert(rubbishCallTransitions.begin(), rubbishCallTransitions.end()); + + auto localTransitions = d.getLocalTransitions(); + localTransitions.insert(rubbishLocalTransitions.begin(), rubbishLocalTransitions.end()); + + for(const ext::set<ext::pair<StateType,StateType>>& state : states) { + const ext::set<StateType> dSubSet = retrieveDSubSet(unpackFromStateLabel(state)); + + bool originalCallsLocals = false; + for(const auto& transition : n.getCallTransitions()) { + if(dSubSet.count(transition.first.first)) { + originalCallsLocals = true; + break; + } + } + if(!originalCallsLocals) for(const auto& transition : n.getLocalTransitions()) { + if(dSubSet.count(transition.first.first)) { + originalCallsLocals = true; + break; + } + } + + if(!originalCallsLocals) continue; + bool deterministicCallLocals = false; + + for(const auto& transition : callTransitions) { + if(state == transition.first.first) { + deterministicCallLocals = true; + break; + } + } + if(deterministicCallLocals) for(const auto& transition : localTransitions) { + if(state == transition.first.first) { + deterministicCallLocals = true; + break; + } + } + + if(originalCallsLocals && !deterministicCallLocals) dirtyStates.insert(state); + + } + return dirtyStates; +} + +template<class T, class DeterministicStateType > +void localClosure(ext::set<DeterministicStateType>& states, const ext::set<DeterministicStateType>& oldStates, const T & d) { + ext::set<DeterministicStateType> newStates; + + for(const DeterministicStateType& state : oldStates) { + for(const auto& transition : d.getLocalTransitions()) { + if(transition.second != state) continue; + + if(!states.count(transition.first.first)) { + states.insert(transition.first.first); + newStates.insert(transition.first.first); + } + } + + for(const auto& transition : d.getReturnTransitions()) { + if(transition.second != state) continue; + + const auto& popSymbol = std::get<2>(transition.first); + if(popSymbol == d.getBottomOfTheStackSymbol()) continue; + + const DeterministicStateType & statePart = unpackFromStackSymbol ( popSymbol ).first; + + if(!states.count(statePart)) { + states.insert(statePart); + newStates.insert(statePart); + } + } + } + + if(newStates.empty()) return; + localClosure(states, newStates, d); +} + +template<class T, class DeterministicStateType, class InputSymbolType, class DeterministicPushdownStoreSymbolType, class R> +ext::set<ext::pair<DeterministicStateType, DeterministicPushdownStoreSymbolType>> existsDirtyStateSymbol(const T& d, const ext::set<DeterministicStateType>& rubbishStates, const ext::map < ext::pair < DeterministicStateType, InputSymbolType>, ext::pair < DeterministicStateType, DeterministicPushdownStoreSymbolType > > & rubbishCallTransitions, const ext::map < ext::tuple < DeterministicStateType, InputSymbolType, DeterministicPushdownStoreSymbolType >, DeterministicStateType > & rubbishReturnTransitions, const R& n) { + ext::set<ext::pair<DeterministicStateType, DeterministicPushdownStoreSymbolType>> dirtyStateSymbols; + + ext::set<DeterministicStateType> states = d.getStates(); + states.insert(rubbishStates.begin(), rubbishStates.end()); + + auto callTransitions = d.getCallTransitions(); + callTransitions.insert(rubbishCallTransitions.begin(), rubbishCallTransitions.end()); + + auto returnTransitions = d.getReturnTransitions(); + returnTransitions.insert(rubbishReturnTransitions.begin(), rubbishReturnTransitions.end()); + + for(const DeterministicStateType& state : states) { + bool originalPops = false; + auto dSubSet = retrieveDSubSet(unpackFromStateLabel(state)); + + for(const auto& transition : n.getReturnTransitions()) { + if(dSubSet.count(std::get<0>(transition.first))) { + originalPops = true; + break; + } + } + if(!originalPops) continue; + + ext::set<DeterministicStateType> lc { state }; + localClosure(lc, ext::set<DeterministicStateType>{state}, d); //intentional copy + + ext::set<DeterministicPushdownStoreSymbolType> topSymbols; + for(const DeterministicStateType& localState : lc) { + for(const auto& transition : callTransitions) { + const auto& to = transition.second; + if(localState != to.first) continue; + + topSymbols.insert(to.second); + } + + if(d.getInitialState() == localState) + topSymbols.insert(d.getBottomOfTheStackSymbol()); + } + + for(const auto& transition : returnTransitions) { + if(state != std::get<0>(transition.first)) continue; -const ext::set<ext::pair<DefaultStateType, DefaultStateType>> & unpackFromStateLabel(const DefaultStateType& data); + topSymbols.erase(std::get<2>(transition.first)); + } + + for(const DeterministicPushdownStoreSymbolType& topSymbol : topSymbols) + dirtyStateSymbols.insert(ext::make_pair(state, topSymbol)); + } + + return dirtyStateSymbols; +} -DefaultSymbolType packToStackSymbolLabel(ext::pair<DefaultStateType, DefaultSymbolType>&& data); - -const ext::pair<DefaultStateType, DefaultSymbolType> & unpackFromDVPAStackSymbol(const DefaultSymbolType& symbol); - -DefaultSymbolType packToStackSymbolLabel(ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>>&& data); - -const ext::pair<DefaultStateType, ext::variant<DefaultEpsilonType, DefaultSymbolType>> & unpackFromDRHDPDAStackSymbol(const DefaultSymbolType& symbol); - -ext::set<DefaultStateType> retrieveDSubSet(const ext::set<ext::pair<DefaultStateType, DefaultStateType>>& localOperation); - -ext::set<ext::pair<DefaultStateType, DefaultStateType>> createIdentity(const ext::set<DefaultStateType>& states); - -template<class T, class S, class R> -ext::set<DefaultStateType> existsDirtyState(const T& d, const ext::set<DefaultStateType>& rubbishStates, const ext::map<ext::pair<DefaultStateType, S>, ext::pair<DefaultStateType, DefaultSymbolType> >& rubbishCallTransitions, const ext::map<ext::pair<DefaultStateType, S>, DefaultStateType>& rubbishLocalTransitions, const R& n); - -void localClosure(ext::set<DefaultStateType>& states, const ext::set<DefaultStateType>& oldStates, const automaton::RealTimeHeightDeterministicDPDA < > & d); -void localClosure(ext::set<DefaultStateType>& states, const ext::set<DefaultStateType>& oldStates, const automaton::VisiblyPushdownDPDA < > & d); - -template<class T, class S, class R> -ext::set<ext::pair<DefaultStateType, DefaultSymbolType>> existsDirtyStateSymbol(const T& d, const ext::set<DefaultStateType>& rubbishStates, const ext::map<ext::pair<DefaultStateType, S>, ext::pair<DefaultStateType, DefaultSymbolType> >& rubbishCallTransitions, const ext::map<ext::tuple<DefaultStateType, S, DefaultSymbolType>, DefaultStateType>& rubbishReturnTransitions, const R& n); } /* namespace determinize */