-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAutomata.cpp
426 lines (327 loc) · 16.7 KB
/
Automata.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
// by - Siddharth Singh
//THEORY OF AUTOMATA
//CODE ASSIGNMENT
#include <bits/stdc++.h>
#include<cstdlib>
#define pb push_back
using namespace std;
//BFS= Breadth First Search ,being used here to cut down the states given in the input DFA that are unreachable from the initial state
//Can be seen as disconnected component in the transition graph
void bfs(string s,map<string,bool> &reach, map<string,vector<string> > & m)
{
queue<string> q;
q.push(s);
reach[s]=true;
while(q.size()){
string p =q.front();
q.pop();
for( int i =0; i<m[p].size(); i++)
{
if(reach[m[p][i]]==false)
{
reach[m[p][i]]=true;
q.push(m[p][i]);
}
}
}
}
int main()
{
system("Color 5F");
cout<<"\n\n STATE MINIMISATION PROGRAM FOR A DFA\n";
cout<<" _________________________________________\n\n";
cout<<"========================================================================================================================\n\n\n";
// A vector of string to store the input states(Accepts states in any form like q1,q2....or a, b...)
vector<string> input_states;
// A vector of string to store the final states after removing the unreachable states from start state
vector<string> states;
// A vector of string to store the alphabets (accepts any input of the form a,b,c..or 1,2,3...)
vector<string> alphabets;
// A map to store the transition table of the input DFA
// stores as- map[(q1,a)] gives the state achieved after providing input a at the state q1
map< pair<string,string>,string> transition_table;
//holds the start state
string start_state;
// stores all the states which are non-final
vector<string> non_final_states;
// stores all the state which are final
vector<string> final_states;
// A map marking if a state is reachable from the start state
map<string, bool> is_reachable;
//Taking input the number of states in the input DFA
int number_of_states ;
cout<<"Enter Number Of States:\n";
cin>>number_of_states;
//Taking input the states
cout<<"Enter "<< number_of_states <<" Number Of State(s)\n";
for(int i=0; i<number_of_states; i++)
{
string state;
cin>>state;
input_states.pb(state);
is_reachable[state]=false;
}
//Taking inputs the alphabets for the DFA
cout<<"Enter number of alphabets\n";
int number_of_alphabets;
cin>>number_of_alphabets;
cout<<"Enter "<<number_of_alphabets<<" number of alphabet(s)\n";
for(int i=0; i<number_of_alphabets; i++)
{
string alphabet;
cin>>alphabet;
alphabets.pb(alphabet);
}
//Taking input the start state
cout<<"Enter initial state\n";
cin>>start_state;
//Taking input final states of the DFA
cout<<"Enter number of final states\n";
int number_of_final_states;
cin>>number_of_final_states;
cout<<"Enter "<<number_of_final_states<<" number of final state(s)\n";
for(int i =0; i<number_of_final_states; i++)
{
string final_state;
cin>>final_state;
final_states.pb(final_state);
}
// A map acting as adjacency list for the dfs method (stores the states that can be reached from the gin state)
// Like m[q1] gives the list of the states that can be reached directly through q1 on taking an alphabet
map<string,vector<string> > transition_rows_in_a_map;
//Taking input the transition table
for(int i=0; i<number_of_states; i++)
{
cout<<"For state: '"<<input_states[i]<<"' input the transition row\n\n";
for(int j=0; j<number_of_alphabets; j++)
{
cout<<"For alphabet '"<<alphabets[j]<<"' input next state\n";
string next_state;
cin>> next_state;
transition_rows_in_a_map[input_states[i]].pb(next_state);
cout<<"\n";
transition_table[make_pair(input_states[i], alphabets[j])]= next_state;
}
}
system("cls");
system("Color E4");
cout<<"\n\n STATE MINIMISATION PROGRAM FOR A DFA\n";
cout<<" _________________________________________\n\n";
cout<<"======================================================================================================================\n\n\n";
// DFS called here to remove unreachable states
bfs(start_state,is_reachable,transition_rows_in_a_map);
// Storing the reachable states in the vector named states and simultaneously printing unreachable states
for(auto it= is_reachable.begin(); it!=is_reachable.end(); it++)
{
if(it->second)
states.pb(it->first);
else
cout<<"Removing state "<<it->first<<" as it is unreachable from the initial state\n\n";
}
//Storing the non-final states in the vector non_final
for(int i= 0; i<states.size(); i++)
{
if(find(final_states.begin(),final_states.end(),states[i])==final_states.end()) // if a particular state is not found in final states list
// then it is non final
{
non_final_states.pb(states[i]);
}
}
//This is a vector of vectors of vectors of string each row in the vector equivalence class represents ith class
//Each row of this vector is itself a vector that holds the partitions for that equivalence class
// equivalence_classes[0] represents the 0th equivalence class
//equivalence_classes[0][0] represents 0th partition of the 0th equivalence class
//equivalence_classes[0][0][0] epresents 0th element of the 0th partition of the 0th equivalence class
vector< vector< vector <string> > > equivalence_classes;
//storing the 0th equivalence class as it consists of two partitions set of final and non-final states
vector< vector<string> >zero_equivalence;
zero_equivalence.pb(non_final_states);
zero_equivalence.pb(final_states);
equivalence_classes.pb(zero_equivalence);
//this is the major logic of the program
//here we use the equivalence theorem for minimisation
//we already have the 0th equivalence class
//for each subsequent equivalence classes we check for the partitions in the previous class
//after generating the ith equivalence class we compare it with (i-1)th equivalence class if it comes same we break otherwise we continue repeating
for( int i=1;; i++)
{
map<string,bool> visited;
for(int u = 0; u<states.size(); u++)
visited[states[u]]=false;
vector<vector<string> > equivalence_row;
for(int j=0; j<equivalence_classes[i-1].size(); j++ )
{
for(int k=0; k<equivalence_classes[i-1][j].size(); k++)
{
if( visited[equivalence_classes[i-1][j][k]]== false)
{
vector<string> equivalence;
equivalence.pb(equivalence_classes[i-1][j][k]);
visited[equivalence_classes[i-1][j][k]]= true;
for(int l= k+1; l<equivalence_classes[i-1][j].size(); l++)
{
if( visited[equivalence_classes[i-1][j][l]]== false)
{
bool flag =false;
for(int m =0; m<alphabets.size(); m++)
{
flag = false;
for(int b=0; b<equivalence_classes[i-1].size(); b++ )
{
if(find(equivalence_classes[i-1][b].begin(),equivalence_classes[i-1][b].end(),transition_table[make_pair(equivalence_classes[i-1][j][k],alphabets[m])])!=equivalence_classes[i-1][b].end()
&&
find(equivalence_classes[i-1][b].begin(),equivalence_classes[i-1][b].end(),transition_table[make_pair(equivalence_classes[i-1][j][l],alphabets[m])])!=equivalence_classes[i-1][b].end() )
{
flag = true;
break;
}
}
if(!flag)
break;
}
if(flag==true)
{
equivalence.pb(equivalence_classes[i-1][j][l]);
visited[equivalence_classes[i-1][j][l]]= true;
}
}
}
if(equivalence.size()>0)
equivalence_row.pb(equivalence);
}
}
}
if(equivalence_row.size()>0)
equivalence_classes.pb(equivalence_row);
//checking ith equivalence if it is equal to (i-1)th equivalence class
if(equivalence_classes[i-1].size()==equivalence_classes[i].size())
{
bool flag = true;
for(int z =0; z<equivalence_classes[i-1].size(); z++)
{
if(equivalence_classes[i-1][z].size()!=equivalence_classes[i][z].size())
{
flag=false;
break;
}
}
if(flag)
{
for(int z =0; z<equivalence_classes[i-1].size(); z++)
{
for(int x =0; x<equivalence_classes[i-1][z].size(); x++)
{
if(equivalence_classes[i-1][z][x]!=equivalence_classes[i][z][x])
{
flag=false;
}
}
}
}
if(flag)
break;
}
}
//printing the final equivalence class with all the partitions
cout<<"Final equivalence class is: \n";
int g = equivalence_classes.size()-1;
cout<<"Equivalence class number: "<<g-1<<"\n";
for(int v = 0; v<equivalence_classes[g].size(); v++)
{
cout<<"\nPartition number:- "<<v<<"\n\n";
cout<<"{ ";
for(int p = 0; p<equivalence_classes[g][v].size(); p++)
{
cout<<equivalence_classes[g][v][p];
if(p!=equivalence_classes[g][v].size()-1)
cout<<", ";
}
cout<<" }\n";
}
cout<<"\n\n\n TRANSITION TABLE FOR MINIMIZED DFA\n";
cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\n";
// printing the transition table for the minimised dfa
// each partition in the final equivalence class represents one state
for(int i =0; i<equivalence_classes[g].size(); i++)
{
if(find(equivalence_classes[g][i].begin(),equivalence_classes[g][i].end(),start_state)!=equivalence_classes[g][i].end())
{
string curr="[";
for(int j = 0; j<equivalence_classes[g][i].size(); j++)
{
if(j!=equivalence_classes[g][i].size()-1)
curr=curr+equivalence_classes[g][i][j]+" ";
else
curr=curr+equivalence_classes[g][i][j];
}
curr+="]";
cout<<"Initial state of the minimized DFA is :- "<<curr<<"\n\n";
break;
}
}
cout<<"Final states of the minimized DFA is/are :- ";
for(int i =0; i<equivalence_classes[g].size(); i++)
{
for(int k= 0; k<final_states.size(); k++)
{
if(find(equivalence_classes[g][i].begin(),equivalence_classes[g][i].end(),final_states[k])!=equivalence_classes[g][i].end())
{
string curr="[";
for(int j = 0; j<equivalence_classes[g][i].size(); j++)
{
if(j!=equivalence_classes[g][i].size()-1)
curr=curr+equivalence_classes[g][i][j]+" ";
else
curr=curr+equivalence_classes[g][i][j];
}
curr+="]";
cout<<curr<<" ";
break;
}
}
}
cout<<"\n________________________________________________________\n\n";
//transition table printing starts here
cout<<setw(14)<<"State"<<setw(28)<<"Inputs\n";
cout<<"________________________________________________________\n\n";
cout<<setw(30)<<" ";
for(int i = 0; i<alphabets.size(); i++)
{
cout<<alphabets[i]<<setw(23);
}
cout<<"\n________________________________________________________\n\n";
for(int i =0; i<equivalence_classes[g].size(); i++)
{
string curr="[";
for(int j = 0; j<equivalence_classes[g][i].size(); j++)
{
if(j!=equivalence_classes[g][i].size()-1)
curr=curr+equivalence_classes[g][i][j]+" ";
else
curr=curr+equivalence_classes[g][i][j];
}
curr+="]";
cout<<setw(13)<<curr;
for(int j=0; j<alphabets.size(); j++)
{
for(int m = 0; m<equivalence_classes[g].size(); m++)
{
if(find(equivalence_classes[g][m].begin(),equivalence_classes[g][m].end(),transition_table[make_pair(equivalence_classes[g][i][0],alphabets[j])])!=equivalence_classes[g][m].end())
{
string transited = "[";
for(int x=0; x<equivalence_classes[g][m].size(); x++)
{
if(x!=equivalence_classes[g][m].size()-1)
transited= transited+equivalence_classes[g][m][x]+" ";
else
transited= transited+equivalence_classes[g][m][x];
}
transited+="]";
cout<<setw(21)<<transited;
break;
}
}
}
cout<<"\n________________________________________________________\n\n";
}
}