-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnfa.cpp
121 lines (86 loc) · 4.19 KB
/
nfa.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "nfa.h"
#include <deque>
std::set<int> NFA::create_initial_state() {
std::set<int> epsilon_reached_states = this->transition_function(this->initial_state, this->alphabet_number);
epsilon_reached_states.insert(this->initial_state);
return epsilon_reached_states;
}
bool NFA::is_dfa_state_final(const std::set<int> &_dfa_state) {
for (const int &separate_state: _dfa_state) {
if (this->is_state_final(separate_state)) {
return true;
}
}
return false;
}
std::map<std::set<int>, std::vector<std::set<int>>> NFA::create_transition_graph(const std::set<int> &_initial_state) {
std::map<std::set<int>, std::vector<std::set<int>>> new_transition_graph;
std::deque<std::set<int>> creation_queue{_initial_state};
std::set<std::set<int>> visited_states;
while (!creation_queue.empty()) {
std::set<int> current_state = creation_queue.front();
creation_queue.pop_front();
new_transition_graph[current_state] = std::vector<std::set<int>>(this->alphabet_number);
for (int letter = 0; letter < this->alphabet_number; letter++) {
std::set<int> reaching_states;
for (const int &separate_state: current_state) {
for (int reaching_state: this->transition_function(separate_state, letter)) {
reaching_states.insert(reaching_state);
for (int epsilon_reached_state: this->transition_function(reaching_state, this->alphabet_number)) {
reaching_states.insert(epsilon_reached_state);
}
}
}
new_transition_graph[current_state][letter] = reaching_states;
if (!visited_states.count(reaching_states) && !reaching_states.empty()) {
creation_queue.push_back(reaching_states);
visited_states.insert(current_state);
}
}
}
return new_transition_graph;
}
int NFA::add_to_rename_table(const std::set<int> &_state, int &_new_state_name, std::set<std::set<int>> &_added_states,
std::map<std::set<int>, int> &_rename_table) {
if (!_added_states.count(_state)) {
_added_states.insert(_state);
_rename_table[_state] = _new_state_name;
_new_state_name++;
}
return _rename_table[_state];
}
std::pair<std::set<int>, std::map<int, std::vector<int>>>
NFA::transition_graph_updated(const std::set<int> &_old_initial_state,
const std::map<std::set<int>, std::vector<std::set<int>>> &nfa_transition_graph) {
std::map<int, std::vector<int>> new_transition_graph;
std::set<int> final_states;
std::map<std::set<int>, int> rename_table;
std::set<std::set<int>> added_states;
int new_name_state = 0;
rename_table[_old_initial_state] = new_name_state;
for (const auto &old_state: nfa_transition_graph) {
int new_assigned_name = NFA::add_to_rename_table(old_state.first, new_name_state, added_states, rename_table);
new_transition_graph[new_assigned_name] = std::vector<int>(this->alphabet_number);
if (this->is_dfa_state_final(old_state.first)) {
final_states.insert(rename_table[old_state.first]);
}
int index = 0;
for (const auto &reaching_state: old_state.second) {
new_transition_graph[new_assigned_name][index] = NFA::add_to_rename_table(
reaching_state, new_name_state, added_states, rename_table);
index++;
if (this->is_dfa_state_final(reaching_state)) {
final_states.insert(rename_table[reaching_state]);
}
}
}
return std::make_pair(final_states, new_transition_graph);
}
DFA NFA::convert_to_dfa() {
std::set<int> new_initial_state = this->create_initial_state();
auto dfa_transition_graph = this->create_transition_graph(new_initial_state);
auto pair_data = this->transition_graph_updated(new_initial_state, dfa_transition_graph);
std::set<int> dfa_final_states = pair_data.first;
std::map<int, std::vector<int>> renamed_dfa_transition_graph = pair_data.second;
return {DFA(0, this->alphabet_number, dfa_final_states, renamed_dfa_transition_graph)};
}