10 #include <unordered_set> 38 template<
typename Sigma>
48 m_states.insert(initial);
49 m_initialState = initial;
51 m_acceptingStates.insert(initial);
63 m_states.insert(state);
65 m_acceptingStates.insert(state);
80 if (m_states.find(p) == m_states.end()) {
81 std::ostringstream error;
82 error << p <<
" is not known when adding the transition " << p <<
" --" << symbol <<
"--> " << q;
83 throw std::out_of_range(error.str());
85 else if (m_states.find(q) == m_states.end()) {
86 std::ostringstream error;
87 error << q <<
" is not known when adding the transition " << p <<
" --" << symbol <<
"--> " << q;
88 throw std::out_of_range(error.str());
91 m_transitions[p][symbol] = q;
100 unsigned int state = m_initialState;
101 for (
const Sigma &a : word) {
102 auto itr = m_transitions.find(state);
103 if (itr == m_transitions.end()) {
106 auto tran = itr->second.find(a);
108 if (tran != itr->second.end()) {
109 state = tran->second;
125 unsigned int state = m_initialState;
126 for (
const Sigma &a : word) {
127 auto tran = m_transitions.find(std::make_pair(state, a));
129 if (tran != m_transitions.end()) {
130 state = tran->second;
145 return m_states.size();
153 std::ostringstream dot;
154 dot <<
"digraph deterministic_finite_automaton {\n";
155 dot <<
"\trankdir=LR;\n";
156 dot <<
"\tsize=\"8.5\"\n";
157 process_states_dot(dot);
158 process_transitions_dot(dot);
170 std::unique_ptr<DFA<T>>
convert(
const std::map<Sigma, T> &conversionMap)
const {
171 std::unique_ptr<DFA<T>> converted = std::make_unique<DFA<T>>(m_initialState,
isAcceptingState(m_initialState));
173 for (
unsigned int state : m_states) {
174 if (state != m_initialState) {
179 for (
auto transition : m_transitions) {
180 unsigned int p = transition.first;
181 for (
auto t : transition.second) {
182 T a = conversionMap.at(t.first);
183 unsigned int q = t.second;
184 converted->addTransition(p, a, q);
188 return std::move(converted);
197 return m_acceptingStates.find(state) != m_acceptingStates.end();
204 const std::unordered_set<unsigned int> &
getStates()
const {
215 return m_acceptingStates;
225 return m_initialState;
233 const std::map<unsigned int, std::map<Sigma, unsigned int>>
getTransitions()
const {
234 return m_transitions;
243 return m_states.find(state) != m_states.end();
250 std::unordered_set<unsigned int> m_states;
254 unsigned int m_initialState;
258 std::map<unsigned int, std::map<Sigma, unsigned int>> m_transitions;
262 std::unordered_set<unsigned int> m_acceptingStates;
269 void process_states_dot(std::ostringstream& dot)
const {
271 dot <<
"\tnode [shape=none, label=\"\"] qi\n";
272 for (
int state : m_states) {
273 dot <<
"\tnode [shape=";
276 dot <<
"doublecircle";
282 dot <<
", label=\"q" << state <<
"\"] q" << state <<
";\n";
290 void process_transitions_dot(std::ostringstream &dot)
const {
292 dot <<
"\tqi -> q" << m_initialState <<
";\n";
294 for (
auto state : m_transitions) {
295 unsigned int start = state.first;
296 for (
auto transition : state.second) {
297 Sigma symbol = transition.first;
298 unsigned int end = transition.second;
299 dot <<
"\tq" << start <<
" -> q" << end <<
" [label=\"" << symbol <<
"\"];\n";
bool isState(unsigned int state) const
Checks if the given state number is in the states set.
The namespace of the library.
const std::unordered_set< unsigned int > & getAcceptingStates() const
Returns the set of accepting states of this DFA.
bool isAcceptingState(unsigned int state) const
Tests whether the given state is a final (or accepting) state.
unsigned int getNumberOfStates() const
Returns the number of states in this DFA.
std::unique_ptr< DFA< T > > convert(const std::map< Sigma, T > &conversionMap) const
Creates a new DFA with exactly the same number of states and the same transitions but the type of the...
bool isAccepting(Expr f_value)
bool isAccepted(const std::list< Sigma > &word)
Tests whether the word is accepted by the DFA.
const std::unordered_set< unsigned int > & getStates() const
Returns the set of states in this DFA.
std::string to_dot() const
Constructs a string that is the representation of the DFA in the DOT language.
bool isAccepted(const std::vector< Sigma > &word)
Tests whether the word is accepted by the DFA.
DFA(unsigned int initial, bool isAccepting=false)
Constructs the DFA.
void addState(unsigned int state, bool isAccepting=false)
Adds a state to the DFA.
void addTransition(unsigned int p, Sigma symbol, unsigned int q)
Adds a transition to the DFA.
A Deterministic Finite Automaton.
const std::map< unsigned int, std::map< Sigma, unsigned int > > getTransitions() const
Returns the function delta.
unsigned int getInitialState() const
Returns the initial state of this DFA.