Skip to content
Snippets Groups Projects
Commit 7136b31e authored by Jan Trávníček's avatar Jan Trávníček
Browse files

finish templating elgo algorithms

parent 50c88b57
No related branches found
No related tags found
No related merge requests found
...@@ -7,100 +7,22 @@ ...@@ -7,100 +7,22 @@
   
#include "ReachableStates.h" #include "ReachableStates.h"
   
#include <automaton/FSM/ExtendedNFA.h>
#include <automaton/FSM/CompactNFA.h>
#include <automaton/FSM/EpsilonNFA.h>
#include <automaton/FSM/NFA.h>
#include <automaton/FSM/DFA.h>
#include <set>
#include <map>
#include <queue>
namespace automaton { namespace automaton {
   
namespace properties { namespace properties {
   
namespace efficient { namespace efficient {
   
std::set<label::Label> ReachableStates::reachableStates(const Automaton& automaton) { std::set<DefaultStateType> ReachableStates::reachableStates(const Automaton& automaton) {
return dispatch(automaton.getData()); return dispatch(automaton.getData());
} }
   
template<class T> auto ReachableStatesEpsilonNFA = ReachableStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::EpsilonNFA < > >(ReachableStates::reachableStates);
std::set<label::Label> ReachableStates::reachableStates( const T & fsm ) { auto ReachableStatesNFA = ReachableStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::NFA < > >(ReachableStates::reachableStates);
std::map<label::Label, std::set<label::Label>> transitions; auto ReachableStatesCompactNFA = ReachableStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::CompactNFA < > >(ReachableStates::reachableStates);
for(const auto& transition : fsm.getTransitions()) auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::ExtendedNFA < > >(ReachableStates::reachableStates);
transitions[transition.first.first].insert(transition.second.begin(), transition.second.end()); auto ReachableStatesMultiInitialStateNFA = ReachableStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::MultiInitialStateNFA < >>(ReachableStates::reachableStates);
auto ReachableStatesDFA = ReachableStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::DFA < > >(ReachableStates::reachableStates);
std::deque<label::Label> queue { fsm.getInitialState( ) };
std::set<label::Label> visited { fsm.getInitialState( ) };
while( !queue.empty() ) {
const std::set<label::Label>& to = transitions[queue.front()];
queue.pop_front();
for(const label::Label& process : to)
if(visited.insert(process).second) {
queue.push_back(std::move(const_cast<label::Label&>(process)));
}
}
return visited;
}
auto ReachableStatesEpsilonNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::EpsilonNFA < > >(ReachableStates::reachableStates);
auto ReachableStatesNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA < > >(ReachableStates::reachableStates);
auto ReachableStatesCompactNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA < > >(ReachableStates::reachableStates);
auto ReachableStatesExtendedNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA < > >(ReachableStates::reachableStates);
template<>
std::set<label::Label> ReachableStates::reachableStates( const automaton::MultiInitialStateNFA < > & fsm ) {
std::map<label::Label, std::set<label::Label>> transitions;
for(const auto& transition : fsm.getTransitions())
transitions[transition.first.first].insert(transition.second.begin(), transition.second.end());
std::deque<label::Label> queue ( fsm.getInitialStates( ).begin(), fsm.getInitialStates().end() );
std::set<label::Label> visited = fsm.getInitialStates( );
while( !queue.empty() ) {
const std::set<label::Label>& to = transitions[queue.front()];
queue.pop_front();
for(const label::Label& process : to)
if(visited.insert(process).second) {
queue.push_back(std::move(const_cast<label::Label&>(process)));
}
}
return visited;
}
auto ReachableStatesMultiInitialStateNFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::MultiInitialStateNFA < >>(ReachableStates::reachableStates);
template<>
std::set<label::Label> ReachableStates::reachableStates( const automaton::DFA < > & fsm ) {
std::map<label::Label, std::set<label::Label>> transitions;
for(const auto& transition : fsm.getTransitions())
transitions[transition.first.first].insert(transition.second);
std::deque<label::Label> queue { fsm.getInitialState( ) };
std::set<label::Label> visited { fsm.getInitialState( ) };
while( !queue.empty() ) {
const std::set<label::Label>& to = transitions[queue.front()];
queue.pop_front();
for(const label::Label& process : to)
if(visited.insert(process).second) {
queue.push_back(std::move(const_cast<label::Label&>(process)));
}
}
return visited;
}
auto ReachableStatesDFA = ReachableStates::RegistratorWrapper<std::set<label::Label>, automaton::DFA<>>(ReachableStates::reachableStates);
   
} /* namespace efficient */ } /* namespace efficient */
   
......
...@@ -12,11 +12,17 @@ ...@@ -12,11 +12,17 @@
#include <algorithm> #include <algorithm>
#include <deque> #include <deque>
#include <set> #include <set>
#include <map>
#include <queue>
   
#include <automaton/Automaton.h> #include <automaton/Automaton.h>
#include <automaton/AutomatonFeatures.h> #include <automaton/AutomatonFeatures.h>
   
#include <label/Label.h> #include <automaton/FSM/ExtendedNFA.h>
#include <automaton/FSM/CompactNFA.h>
#include <automaton/FSM/EpsilonNFA.h>
#include <automaton/FSM/NFA.h>
#include <automaton/FSM/DFA.h>
   
namespace automaton { namespace automaton {
   
...@@ -24,17 +30,87 @@ namespace properties { ...@@ -24,17 +30,87 @@ namespace properties {
   
namespace efficient { namespace efficient {
   
class ReachableStates : public std::SingleDispatch<ReachableStates, std::set<label::Label>, const automaton::AutomatonBase &> { class ReachableStates : public std::SingleDispatch<ReachableStates, std::set<DefaultStateType>, const automaton::AutomatonBase &> {
public: public:
static std::set<label::Label> reachableStates( const automaton::Automaton & automaton ); static std::set<DefaultStateType> reachableStates( const automaton::Automaton & automaton );
   
/** /**
* Removes dead states from FSM. Melichar 2.29 * Removes dead states from FSM. Melichar 2.29
*/ */
template<class T> template < class T, class SymbolType = typename automaton::SymbolTypeOfAutomaton < T >, class StateType = typename automaton::StateTypeOfAutomaton < T > >
static std::set<label::Label> reachableStates( const T & fsm ); static std::set<StateType> reachableStates( const T & fsm );
template < class SymbolType, class StateType >
static std::set<StateType> reachableStates( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm );
template < class SymbolType, class StateType >
static std::set<StateType> reachableStates( const automaton::DFA < SymbolType, StateType > & fsm );
}; };
   
template < class T, class SymbolType, class StateType >
std::set<StateType> ReachableStates::reachableStates( const T & fsm ) {
std::map<StateType, std::set<StateType>> transitions;
for(const auto& transition : fsm.getTransitions())
transitions[transition.first.first].insert(transition.second.begin(), transition.second.end());
std::deque<StateType> queue { fsm.getInitialState( ) };
std::set<StateType> visited { fsm.getInitialState( ) };
while( !queue.empty() ) {
const std::set<StateType>& to = transitions[queue.front()];
queue.pop_front();
for(const StateType& process : to)
if(visited.insert(process).second) {
queue.push_back(std::move(const_cast<StateType&>(process)));
}
}
return visited;
}
template < class SymbolType, class StateType >
std::set<StateType> ReachableStates::reachableStates( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm ) {
std::map<StateType, std::set<StateType>> transitions;
for(const auto& transition : fsm.getTransitions())
transitions[transition.first.first].insert(transition.second.begin(), transition.second.end());
std::deque<StateType> queue ( fsm.getInitialStates( ).begin(), fsm.getInitialStates().end() );
std::set<StateType> visited = fsm.getInitialStates( );
while( !queue.empty() ) {
const std::set<StateType>& to = transitions[queue.front()];
queue.pop_front();
for(const StateType& process : to)
if(visited.insert(process).second) {
queue.push_back(std::move(const_cast<StateType&>(process)));
}
}
return visited;
}
template < class SymbolType, class StateType >
std::set<StateType> ReachableStates::reachableStates( const automaton::DFA < SymbolType, StateType > & fsm ) {
std::map<StateType, std::set<StateType>> transitions;
for(const auto& transition : fsm.getTransitions())
transitions[transition.first.first].insert(transition.second);
std::deque<StateType> queue { fsm.getInitialState( ) };
std::set<StateType> visited { fsm.getInitialState( ) };
while( !queue.empty() ) {
const std::set<StateType>& to = transitions[queue.front()];
queue.pop_front();
for(const StateType& process : to)
if(visited.insert(process).second) {
queue.push_back(std::move(const_cast<StateType&>(process)));
}
}
return visited;
}
} /* namespace efficient */ } /* namespace efficient */
   
} /* namespace properties */ } /* namespace properties */
......
...@@ -7,78 +7,22 @@ ...@@ -7,78 +7,22 @@
   
#include "UsefullStates.h" #include "UsefullStates.h"
   
#include <automaton/FSM/ExtendedNFA.h>
#include <automaton/FSM/CompactNFA.h>
#include <automaton/FSM/EpsilonNFA.h>
#include <automaton/FSM/NFA.h>
#include <automaton/FSM/DFA.h>
#include <set>
#include <map>
#include <queue>
namespace automaton { namespace automaton {
   
namespace properties { namespace properties {
   
namespace efficient { namespace efficient {
   
std::set<label::Label> UsefullStates::usefullStates(const Automaton& automaton) { std::set<DefaultStateType> UsefullStates::usefullStates(const Automaton& automaton) {
return dispatch(automaton.getData()); return dispatch(automaton.getData());
} }
   
template<class T> auto UsefullStatesEpsilonNFA = UsefullStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::EpsilonNFA < > >(UsefullStates::usefullStates);
std::set<label::Label> UsefullStates::usefullStates( const T & fsm ) { auto UsefullStatesNFA = UsefullStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::NFA < > >(UsefullStates::usefullStates);
std::map<label::Label, std::set<label::Label>> reversedTransitions; auto UsefullStatesCompactNFA = UsefullStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::CompactNFA < > >(UsefullStates::usefullStates);
for(const auto& transition : fsm.getTransitions()) auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::ExtendedNFA < > >(UsefullStates::usefullStates);
for(const label::Label& to : transition.second) auto UsefullStatesMultiInitialStateNFA = UsefullStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::MultiInitialStateNFA < >>(UsefullStates::usefullStates);
reversedTransitions[to].insert(transition.first.first); auto UsefullStatesDFA = UsefullStates::RegistratorWrapper<std::set<DefaultStateType>, automaton::DFA < > >(UsefullStates::usefullStates);
std::deque<label::Label> queue ( fsm.getFinalStates( ).begin(), fsm.getFinalStates().end() );
std::set<label::Label> visited = fsm.getFinalStates( );
while( !queue.empty() ) {
const std::set<label::Label>& to = reversedTransitions[queue.front()];
queue.pop_front();
for(const label::Label& process : to)
if(visited.insert(process).second) {
queue.push_back(std::move(const_cast<label::Label&>(process)));
}
}
return visited;
}
auto UsefullStatesEpsilonNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::EpsilonNFA < > >(UsefullStates::usefullStates);
auto UsefullStatesNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::NFA < > >(UsefullStates::usefullStates);
auto UsefullStatesCompactNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::CompactNFA < > >(UsefullStates::usefullStates);
auto UsefullStatesExtendedNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::ExtendedNFA < > >(UsefullStates::usefullStates);
auto UsefullStatesMultiInitialStateNFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::MultiInitialStateNFA < >>(UsefullStates::usefullStates);
template<>
std::set<label::Label> UsefullStates::usefullStates( const automaton::DFA < > & fsm ) {
std::map<label::Label, std::set<label::Label>> reversedTransitions;
for(const auto& transition : fsm.getTransitions())
reversedTransitions[transition.second].insert(transition.first.first);
std::deque<label::Label> queue ( fsm.getFinalStates( ).begin(), fsm.getFinalStates().end() );
std::set<label::Label> visited = fsm.getFinalStates( );
while( !queue.empty() ) {
const std::set<label::Label>& to = reversedTransitions[queue.front()];
queue.pop_front();
for(const label::Label& process : to)
if(visited.insert(process).second) {
queue.push_back(std::move(const_cast<label::Label&>(process)));
}
}
return visited;
}
auto UsefullStatesDFA = UsefullStates::RegistratorWrapper<std::set<label::Label>, automaton::DFA<>>(UsefullStates::usefullStates);
   
} /* namespace efficient */ } /* namespace efficient */
   
......
...@@ -12,11 +12,17 @@ ...@@ -12,11 +12,17 @@
#include <algorithm> #include <algorithm>
#include <deque> #include <deque>
#include <set> #include <set>
#include <map>
#include <queue>
   
#include <automaton/Automaton.h> #include <automaton/Automaton.h>
#include <automaton/AutomatonFeatures.h> #include <automaton/AutomatonFeatures.h>
   
#include <label/Label.h> #include <automaton/FSM/ExtendedNFA.h>
#include <automaton/FSM/CompactNFA.h>
#include <automaton/FSM/EpsilonNFA.h>
#include <automaton/FSM/NFA.h>
#include <automaton/FSM/DFA.h>
   
namespace automaton { namespace automaton {
   
...@@ -24,17 +30,64 @@ namespace properties { ...@@ -24,17 +30,64 @@ namespace properties {
   
namespace efficient { namespace efficient {
   
class UsefullStates : public std::SingleDispatch<UsefullStates, std::set<label::Label>, const automaton::AutomatonBase &> { class UsefullStates : public std::SingleDispatch<UsefullStates, std::set<DefaultStateType>, const automaton::AutomatonBase &> {
public: public:
static std::set<label::Label> usefullStates( const automaton::Automaton & automaton ); static std::set<DefaultStateType> usefullStates( const automaton::Automaton & automaton );
   
/** /**
* Removes dead states from FSM. Melichar 2.32 * Removes dead states from FSM. Melichar 2.32
*/ */
template<class T> template < class T, class SymbolType = typename automaton::SymbolTypeOfAutomaton < T >, class StateType = typename automaton::StateTypeOfAutomaton < T > >
static std::set<label::Label> usefullStates( const T & fsm ); static std::set<StateType> usefullStates( const T & fsm );
template < class SymbolType, class StateType >
static std::set<StateType> usefullStates( const automaton::DFA < SymbolType, StateType > & fsm );
}; };
   
template < class T, class SymbolType, class StateType >
std::set<StateType> UsefullStates::usefullStates( const T & fsm ) {
std::map<StateType, std::set<StateType>> reversedTransitions;
for(const auto& transition : fsm.getTransitions())
for(const StateType& to : transition.second)
reversedTransitions[to].insert(transition.first.first);
std::deque<StateType> queue ( fsm.getFinalStates( ).begin(), fsm.getFinalStates().end() );
std::set<StateType> visited = fsm.getFinalStates( );
while( !queue.empty() ) {
const std::set<StateType>& to = reversedTransitions[queue.front()];
queue.pop_front();
for(const StateType& process : to)
if(visited.insert(process).second) {
queue.push_back(std::move(const_cast<StateType&>(process)));
}
}
return visited;
}
template < class SymbolType, class StateType >
std::set<StateType> UsefullStates::usefullStates( const automaton::DFA < SymbolType, StateType > & fsm ) {
std::map<StateType, std::set<StateType>> reversedTransitions;
for(const auto& transition : fsm.getTransitions())
reversedTransitions[transition.second].insert(transition.first.first);
std::deque<StateType> queue ( fsm.getFinalStates( ).begin(), fsm.getFinalStates().end() );
std::set<StateType> visited = fsm.getFinalStates( );
while( !queue.empty() ) {
const std::set<StateType>& to = reversedTransitions[queue.front()];
queue.pop_front();
for(const StateType& process : to)
if(visited.insert(process).second) {
queue.push_back(std::move(const_cast<StateType&>(process)));
}
}
return visited;
}
} /* namespace efficient */ } /* namespace efficient */
   
} /* namespace properties */ } /* namespace properties */
......
...@@ -17,21 +17,21 @@ void trimTest::tearDown() { ...@@ -17,21 +17,21 @@ void trimTest::tearDown() {
} }
   
void trimTest::testTrimAutomaton() { void trimTest::testTrimAutomaton() {
automaton::DFA<> automaton(label::Label(1)); automaton::DFA < > automaton(DefaultStateType(1));
   
automaton.addState(label::Label(1)); automaton.addState(DefaultStateType(1));
automaton.addState(label::Label(2)); automaton.addState(DefaultStateType(2));
automaton.addState(label::Label(3)); automaton.addState(DefaultStateType(3));
automaton.addInputSymbol(alphabet::Symbol("a")); automaton.addInputSymbol(DefaultSymbolType("a"));
automaton.addInputSymbol(alphabet::Symbol("b")); automaton.addInputSymbol(DefaultSymbolType("b"));
   
automaton.addTransition(label::Label(1), alphabet::Symbol("a"), label::Label(2)); automaton.addTransition(DefaultStateType(1), DefaultSymbolType("a"), DefaultStateType(2));
automaton.addTransition(label::Label(2), alphabet::Symbol("b"), label::Label(1)); automaton.addTransition(DefaultStateType(2), DefaultSymbolType("b"), DefaultStateType(1));
automaton.addTransition(label::Label(3), alphabet::Symbol("b"), label::Label(1)); automaton.addTransition(DefaultStateType(3), DefaultSymbolType("b"), DefaultStateType(1));
   
automaton.addFinalState(label::Label(1)); automaton.addFinalState(DefaultStateType(1));
   
automaton::DFA<> trimed = automaton::simplify::Trim::trim(automaton); automaton::DFA < > trimed = automaton::simplify::Trim::trim(automaton);
   
CPPUNIT_ASSERT(trimed.getStates().size() == 2); CPPUNIT_ASSERT(trimed.getStates().size() == 2);
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment