0% found this document useful (0 votes)
298 views34 pages

To Check Whether String Belongs To A Grammar or Not: Algorithm

The document describes an algorithm to calculate the trailing of non-terminals in a grammar. It initializes all trailing values to false, then installs productions of the form A->a(alpha) or A->Ba(alpha) onto a stack. It pops elements from the stack and installs productions of the form A->B(alpha). This calculates the trailing for all non-terminals.

Uploaded by

Hisham Khan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
298 views34 pages

To Check Whether String Belongs To A Grammar or Not: Algorithm

The document describes an algorithm to calculate the trailing of non-terminals in a grammar. It initializes all trailing values to false, then installs productions of the form A->a(alpha) or A->Ba(alpha) onto a stack. It pops elements from the stack and installs productions of the form A->B(alpha). This calculates the trailing for all non-terminals.

Uploaded by

Hisham Khan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 34

TO CHECK WHETHER STRING BELONGS TO A

GRAMMAR OR NOT

ALGORITHM
Start.
Declare two character arrays str[],token[] and initialize integer variables a=0,b=0,c,d. Input
the string from the user.
Repeat steps 5 to 12 till str[a] =’\0’.
If str[a] =='(' or str[a] =='{' then token[b] =’4’, b++.
If str[a] ==')' or str[a] =='}’ then token[b] =’5’, b++.
Check if isdigit(str[a]) then repeat steps 8 till isdigit(str[a])
a++.
a--, token[b] =’6’, b++.
If str[a]=='+’ then token[b]='2',b++.
If(str[a]=='*') then token[b]=’3’,b++.
a++.
token[b]='\0';
then print the token generated for the string .
b=0.
Repeat step 22 to 31 till token[b]!='\0'
c=0.
Repeat step 24 to 30 till (token[b]=='6' and token[b+1]=='2' and token[b+2]=='6') or
(token[b]=='6' and token[b+1]=='3'and token[b+2]=='6') or (token[b]=='4' and
token[b+1]=='6' and token[b+2]=='5') or (token[c]!='\0').
token[c]='6';
c++;
Repeat step 27 to 28 till token[c]!='\0'.
token[c]=token[c+2].
c++.
token[c-2]=’\0’.
print token.
b++.
Compare token with 6 and store the result in d.
If d=0 then print that the string is in the grammar.
Else print that the string is not in the grammar.
Stop.
PROGRAM TO CHECK WHEATHER A STRING BELONGS TO A
GRAMMAR OR NOT.

#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<string.h>
void main()
{
int a=0,b=0,c;
char str[20],tok[11];
clrscr();
printf("Input the expression = ");
gets(str);
while(str[a]!='\0')
{
if((str[a]=='(')||(str[a]=='{'))
{
tok[b]='4';
b++;
}
if((str[a]==')')||(str[a]=='}'))
{
tok[b]='5';
b++;
}
if(isdigit(str[a]))
{
while(isdigit(str[a]))
{
a++;
}
a--;
tok[b]='6';
b++;
}
if(str[a]=='+')
{
tok[b]='2';
b++;
}
if(str[a]=='*')
{
tok[b]='3';
b++;
}
a++;
}
tok[b]='\0';
puts(tok);
b=0;
while(tok[b]!='\0')
{

if(((tok[b]=='6')&&(tok[b+1]=='2')&&(tok[b+2]=='6'))||((tok[b]=='6')&&(tok[b+1
]=='3')&&(tok[b+2]=='6'))||((tok[b]=='4')&&(tok[b+1]=='6')&&(tok[b+2]=='5'))/*||((tok[b
]!=6)&&(tok[b+1]!='\0'))*/)
{
tok[b]='6';
c=b+1;
while(tok[c]!='\0')
{
tok[c]=tok[c+2];
c++;
}
tok[c]='\0';
puts(tok);
b=0;
}
else
{
b++;
puts(tok);
}
}
int d;
d=strcmp(tok,"6");
if(d==0)
{
printf("It is in the grammar.");
}
else
{
printf("It is not in the grammar.");
}
getch();
}
OUTPUT
Input the expression = (23+)
4625
4625
4625
4625
4625
It is not in the grammar.

Input the expression = (2+(3+4)+5)


46246265265
46246265265
46246265265
46246265265
46246265265
462465265
462465265
462465265
462465265
4626265
4626265
46265
46265
465
6
6
It is in the grammar.
Practical-3
TO CALCULATE LEADING OF NON-TERMINALS

ALGORITHM
1. Start
2. For each nonterminal A and terminal a do L(A,a):= false;
3. For each production of the form A->a or A->B do
INSTALL(A,a);
4. While STACK not empty repeat step 5& 6
5. Pop top pair (B,a) from STACK;
6. For each production of the form A->B do
INSTALL(A,a)

7. Stop

Algorithm For INSTALL(A,a)

1. Start
2. If L(A,a) not present do step 3 and 4.
3 . Make L(A,a)=True
4 . Push (A,a) onto stack
5 . Stop
PROGRAM IS TO CALCULATE LEADING FOR ALL
THE NON-TERMINALS OF THE GIVEN GRAMMAR

#include<conio.h>
#include<stdio.h>

char arr[18][3] =
{
{'E','+','F'},{'E','*','F'},{'E','(','F'},{'E',')','F'},{'E','i','F'},{'E','$','F'},
{'F','+','F'},{'F','*','F'},{'F','(','F'},{'F',')','F'},{'F','i','F'},{'F','$','F'},
{'T','+','F'},{'T','*','F'},{'T','(','F'},{'T',')','F'},{'T','i','F'},{'T','$','F'}, };

char prod[6] = "EETTFF";


char res[6][3]=
{
{'E','+','T'},{'T','\0'},
{'T','*','F'},{'F','\0'},
{'(','E',')'},{'i','\0'}, };
char stack [5][2];
int top = -1;
void install(char pro,char re)
{
int i;
for(i=0;i<18;++i)
{
if(arr[i][0]==pro && arr[i][1]==re)
{
arr[i][2] = 'T';
break;
}
}
++top;
stack[top][0]=pro;
stack[top][1]=re;
}
void main()
{
int i=0,j;
char pro,re,pri=' ';
clrscr();
for(i=0;i<6;++i)
{
for(j=0;j<3 && res[i][j]!='\0';++j)
{
if(res[i][j]
=='+'||res[i][j]=='*'||res[i][j]=='('||res[i][j]==')'||res[i][j]=='i'||res[i][j]=='$')
{
install(prod[i],res[i][j]);
break;
}
}
}
while(top>=0)
{
pro = stack[top][0];
re = stack[top][1];
--top;
for(i=0;i<6;++i)
{
if(res[i][0]==pro && res[i][0]!=prod[i])
{
install(prod[i],re);
}
}
}
for(i=0;i<18;++i)
{
printf("\n\t");
for(j=0;j<3;++j)
printf("%c\t",arr[i][j]);
}
getch();
clrscr();
printf("\n\n");
for(i=0;i<18;++i)
{
if(pri!=arr[i][0])
{
pri=arr[i][0];
printf("\n\t%c -> ",pri);
}
if(arr[i][2] =='T')
printf("%c ",arr[i][1]);
}
getch();}
OUTPUT

E + T
E * T
E ( T
E ) F
E i T
E $ F
F + F
F * F
F ( T
F ) F
F i T
F $ F
T + F
T * T
T ( T
T ) F
T i T
T $ F
PRACTICAL 4

TO CALCULATE TRAILING FOR ALL THE


NONTERMINALS OF THE GIVEN GRAMMMAR
ALGORITHM
1. Start
2. For each non terminal A and terminal a do L(A,a):=false;
3. For each production of the form A->a(alpha) or A-> Ba(alpha) do INSTALL(A,a)
4. While STACK not empty repeat 5 and 6
5. Pop top pair from stack
6. For each production of the form A-> B(alpha) do INSTALL(A,a)
7. Stop

Algorithm For INSTALL(A,a)


1. Start
2. If L[A,a] not present repeat step 3 and 4
3. Make L(A,a)=True
4. Push (A,a) onto stack
5. Stop
THIS PROGRAM IS TO CALCULATE TRAILING FOR
ALL THE NON-TERMINALS OF THE GIVEN
GRAMMMAR
#include<conio.h>
#include<stdio.h>

char arr[18][3] =
{
{'E','+','F'},{'E','*','F'},{'E','(','F'},{'E',')','F'},{'E','i','F'},{'E','$','F'},
{'F','+','F'},{'F','*','F'},{'F','(','F'},{'F',')','F'},{'F','i','F'},{'F','$','F'},
{'T','+','F'},{'T','*','F'},{'T','(','F'},{'T',')','F'},{'T','i','F'},{'T','$','F'}, };
char prod[6] = "EETTFF";
char res[6][3]=
{
{'E','+','T'},{'T','\0','\0'},
{'T','*','F'},{'F','\0','\0'},
{'(','E',')'},{'i','\0','\0'}, };
char stack [5][2];
int top = -1;

void install(char pro,char re)


{
int i;
for(i=0;i<18;++i)
{
if(arr[i][0]==pro && arr[i][1]==re)
{
arr[i][2] = 'T';
break;
}
}
++top;
stack[top][0]=pro;
stack[top][1]=re;
}

void main()
{
int i=0,j;
char pro,re,pri=' ';

clrscr();
for(i=0;i<6;++i)
{
for(j=2;j>=0;--j)
{

if(res[i][j]=='+'||res[i][j]=='*'||res[i][j]=='('||res[i][j]==')'||res[i][j]=='i'||res[i][j]=='$')
{
install(prod[i],res[i][j]);
break;
}
else if(res[i][j]=='E' || res[i][j]=='F' || res[i][j]=='T')
{
if(res[i][j-1]=='+'||res[i][j-1]=='*'||res[i][j-1]=='('||res[i][j-
1]==')'||res[i][j-1]=='i'||res[i][j-1]=='$')
{
install(prod[i],res[i][j-1]);
break;
}
}
}
}

while(top>=0)
{
pro = stack[top][0];
re = stack[top][1];
--top;
for(i=0;i<6;++i)
{
for(j=2;j>=0;--j)
{
if(res[i][0]==pro && res[i][0]!=prod[i])
{
install(prod[i],re);
break;
}
else if(res[i][0]!='\0')
break;
}
}
}
for(i=0;i<18;++i)
{
printf("\n\t");
for(j=0;j<3;++j)
printf("%c\t",arr[i][j]);
}
getch();
clrscr();
printf("\n\n");
for(i=0;i<18;++i)
{
if(pri!=arr[i][0])
{
pri=arr[i][0];
printf("\n\t%c -> ",pri);
}
if(arr[i][2] =='T')
printf("%c ",arr[i][1]);
}
getch();

}
OUTPUT

E + T
E * T
E ( F
E ) T
E i T
E $ F
F + F
F * F
F ( F
F ) T
F i T
F $ F
T + F
T * T
T ( F
T ) T
T i T
T $ F

E -> + * ) i
F -> ) i
T -> * ) i
PRACTICAL 5
PROGRAM FOR COMPUTATION OF FIRST

ALGORITHM
To compute FIRST(X) for all grammar symbols x, apply the following rules until no more
terminals can be added to any FIRST set.

1. if X is terminal, then FIRST(X) is {X}.


2. if X is nonterminal and X-> aα is a production, then add a to FIRST(X). if X->€ to
FIRST(X)
3. if -> Y1,Y2,…….Yk is a production, then for all i such that all of Y1,….Yi-1 are
nonterminals and FIRST(Yj) contains € for j=1,2,…… i-1, add every non-€
symbol in FIRST(Y1) to FIRST(x). if V is in FIRST(Yj) for j=1,2,………k, then
add € to FIRST(X).
PROGRAM FOR COMPUTATION OF FIRST
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char t[5],nt[10],p[5][5],first[5][5],temp; int
i,j,not,nont,k=0,f=0;
clrscr();
printf("\nEnter the no. of Non-terminals in the grammer:");
scanf("%d",&nont);
printf("\nEnter the Non-terminals in the grammer:\n");
for(i=0;i<nont;i++)
{
scanf("\n%c",&nt[i]);
}
printf("\nEnter the no. of Terminals in the grammer: ( Enter e for absiline ) ");
scanf("%d",&not);
printf("\nEnter the Terminals in the grammer:\n");
for(i=0;i<not||t[i]=='$';i++)
{
scanf("\n%c",&t[i]);
}
for(i=0;i<nont;i++)
{
p[i][0]=nt[i];
first[i][0]=nt[i];
}
printf("\nEnter the productions :\n");
for(i=0;i<nont;i++)
{
scanf("%c",&temp);
printf("\nEnter the production for %c ( End the production with '$' sign )
:",p[i][0]);
for(j=0;p[i][j]!='$';)
{
j+=1;
scanf("%c",&p[i][j]);
}
}
for(i=0;i<nont;i++)
{
printf("\nThe production for %c -> ",p[i][0]);
for(j=1;p[i][j]!='$';j++)
{
printf("%c",p[i][j]);
}
}
for(i=0;i<nont;i++)
{
f=0;
for(j=1;p[i][j]!='$';j++)
{
for(k=0;k<not;k++)
{
if(f==1)
break;

if(p[i][j]==t[k])
{
first[i][j]=t[k];
first[i][j+1]='$';
f=1;
break;
}
else if(p[i][j]==nt[k])
{
first[i][j]=first[k][j];
if(first[i][j]=='e')
continue;
first[i][j+1]='$';
f=1;
break;
}
}
}
}
for(i=0;i<nont;i++)
{
printf("\n\nThe first of %c -> ",first[i][0]);
for(j=1;first[i][j]!='$';j++)
{
printf("%c\t",first[i][j]);
}
}
getch();
}
OUTPUT
Enter the no. of Non-terminals in the grammer:3

Enter the Non-terminals in the grammer:


ERT

Enter the no. of Terminals in the grammer: ( Enter e for absiline ) 5

Enter the Terminals in the grammer:


ase*+

Enter the productions :

Enter the production for E ( End the production with '$' sign ) :a+s$

Enter the production for R ( End the production with '$' sign ) :e$

Enter the production for T ( End the production with '$' sign ) :Rs$

The production for E -> a+s


The production for R -> e
The production for T -> Rs

The first of E -> a

The first of R -> e

The first of T -> e s


PRACTICAL-6
PROGRAM TO FIND THE NUMBER OF WHITESPACES AND
NEWLINES CHARACTERS

#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char str[200],ch;
int a=0,space=0,newline=0;
clrscr();
printf("\n enter a string(press escape to quit entering):");
ch=getche();
while((ch!=27) && (a<199))
{
str[a]=ch;
if(str[a]==' ')
{
space++;
}
if(str[a]==13)
{
newline++;
printf("\n");
}
a++;
ch=getche();
}
printf("\n the number of lines used : %d",newline+1);
printf("\n the number of spaces used is : %d",space);
getch();
}
OUTPUT
enter a string(press escape to quit entering):hello!
how r u?
Do you like prog. in compiler?

the number of lines used : 4


the number of spaces used is : 7
PRACTICAL-7
TO IMPLEMENT STACK USING ARRAY
ALGORITHM
INSERTION
PUSH(item)
1. If (item = max of stack)
Print “overflow”
Return
2. top = top + 1
3. stack[top] = item
4. Return

DELETION
POP(item)
1. If (top = - 1)
Print “underflow”
Return
2. Item = stack[top]
3. top = top - 1
4. Return

DISPLAY
1. If top = - 1
Print “underflow”
2. repeat step 3 for i = top to i >= 0
3. Print stack[i]
4. Return
#include<stdio.h>
#include<conio.h>
#define MAXSIZE 10
void push();
int pop();
void traverse();
int stack[MAXSIZE];
int Top=-1;
void main()
{
int choice;
char ch;
do
{
clrscr();
printf("\n1. PUSH ");
printf("\n2. POP ");
printf("\n3. TRAVERSE ");
printf("\nEnter your choice");
scanf("%d",&choice);
switch(choice)
{
case 1: push();
break;
case 2: printf("\nThe deleted element is %d",pop());
break;
case 3: traverse();
break;
default: printf("\nYou Entered Wrong Choice");
}
printf("\nDo You Wish To Continue (Y/N)");
fflush(stdin);
scanf("%c",&ch);
}
while(ch=='Y' || ch=='y');
}

void push()
{
int item;
if(Top == MAXSIZE - 1)
{
printf("\nThe Stack Is Full");
getch();
exit(0);
}
else
{
printf("Enter the element to be inserted");
scanf("%d",&item);
Top= Top+1;
stack[Top] = item;
}
}
int pop()
{
int item;
if(Top == -1)
{
printf("The stack is Empty");
getch();
exit(0);
}
else
{
item = stack[Top];
Top = Top-1;
}
return(item);
}

void traverse()
{
int i;
if(Top == -1)
{
printf("The Stack is Empty");
getch();
exit(0);
}
else
{
for(i=Top;i>=0;i--)
{
printf("Traverse the element");
printf("\n%d",stack[i]);
}
}
}
PRACTICAL-8

TO IMPLEMENT STACK AS LINKED LIST

ALGORITHM
PUSH( )
1. t = newnode( )
2. Enter info to be inserted
3. Read n
4. tinfo = n
5. tnext = top
6. top = t
7. Return

POP( )
1. If (top = NULL)
Print “ underflow”
Return
2. x = top
3. top = top  next
4. delnode(x)
5. Return
// stack using linked list//
#include<stdio.h>
#include<conio.h>
struct stack
{
int no;
struct stack *next;
}
*start=NULL;
typedef struct stack st;
void push();
int pop();
void display();
void main()
{
char ch;
int choice,item;
do
{
clrscr();
printf("\n 1: push");
printf("\n 2: pop");
printf("\n 3: display");
printf("\n Enter your choice");
scanf("%d",&choice);
switch (choice)
{
case 1: push();
break;
case 2: item=pop();
printf("The delete element in %d",item);
break;
case 3: display();
break;
default : printf("\n Wrong choice");
};
printf("\n do you want to continue(Y/N)");
fflush(stdin);
scanf("%c",&ch);
}
while (ch=='Y'||ch=='y');
}
void push()
{
st *node;
node=(st *)malloc(sizeof(st));
printf("\n Enter the number to be insert");
scanf("%d",&node->no);
node->next=start;
start=node;
}
int pop()
{
st *temp;
temp=start;
if(start==NULL)
{
printf("stack is already empty");
getch();
exit();
}
else
{
start=start->next;
free(temp);
}
return(temp->no);
}
void display()
{
st *temp;
temp=start;
while(temp->next!=NULL)
{
printf("\nno=%d",temp->no);
temp=temp->next;
}
printf("\nno=%d",temp->no);
}
PRACTICAL-9

CONSTRUCTING A NFA FROM A REGULAR EXPRESSION

Regular Expressions

Each expression denotes a language, and the following rules are given for the construction of
the denoted languages along with the regular-expression construction rules.

1) ε is a regular expression denoting LRULS.


2) For each a in ∑, a is a regular expression denoting {a}, the language with only one
string, that string consisting of the single symbol a.
3) If R and S are regular expressions denoting languages LR and LS, respectively
then:
a. (R) | (S) is a regular expression denoting LRULS.
b. (R) . (S) is a regular expression denoting LR.LS.
c. (R)* is a regular expression denoting LR*.

NFA
NFA stands for nondeterministic finite-state automata. NFA can be seen as a special kind
of final state machine, which is in a sense an abstract model of a machine with a primitive
internal memory. Let us look at the mathematical definition of NFA.

An NFA ‘A’ consists of:

a. A finite set ‘I’ of input symbols


b. A finite set ‘S’ of states
c. A next-state function ‘f’ from ‘S’ x ‘I’ into P(S)
d. A subset ‘Q’ of ‘S’ of accepting states
e. An initial state ‘s0’ from ‘S’

denoted as A(I, S, f, Q, s0)

If we would explain the above definition to a 12 year old, we could say that an NFA is a set
‘S’ of states that are connected by function ‘f’ (maybe to a smarter 12 year old). NFAs are
represented in two formats: Table and Graph.
ALGORITHM

Input: A regular expression R over alphabet ∑.

Output: An NFA N accepting the language denoted by R.

Method: We first decompose R into its primitive components. For each component we
construct a finite automaton inductively, as follows. Parts 1) and 2) form the basis and part
3) is the induction.

1) For ε we construct the NFA

ε
i f

2) For a in ∑ we construct the NFA

a
i` f`

Each time we need a new state, we give that state a new name. Even if a appears several
times in the regular expression R, we give each instance of a a separate finite automaton with
its own states. In this way, no two states generated either for the basis components to follow
have the same name.

3) Having constructed components for the basis regular expressions, we proceed to


combine them in ways that correspond to the way compound regular expressions
are formed from smaller regular expressions.

For all regular expressions we construct an NFA with one initial and one final state, and with
the extra properties that no more than two edges leave any state. The limit of two on the
number of edges leaving each state is a convenience that allows an efficient
representation of the transition function of the automaton. We observe that each of the above
properties holds for the basis automata constructed in 1) and 2).
Conversion from NFA to DFA:

For each NFA we confined accepting the same language:

Є
2 3
a
Є a b b
Є Є Є
0 1 8 9 10
6 7
Є
Є
b
4 5

The state of DFA represents subset of all states of the NFA this algorithm is often called
subset construction.

To construct equivalent DFA we need to make set of states of all those states that are
reachable with a € transaction. To do this we construct a function to € - closure.
€ - closure(s) can be defined as a set of all those states that can be reached from s on €
transaction alone. If T is a set of states then € - closure(T) is just the union over all states s in T
of € -closure(s).
In algorithmic form of the same is:

begin
Push all states in T onto StACK; Є-
closure(T) := T;
While STACK not empty do
begin
pop s, the top element of STACK, off of STACk; for
each state t with an edge from s to t labeled € do if t is
not in Є-closure(T) do
begin
add t to Є-closure(T);
push t onto STACK
end
end
end

Input: NFA (N)


Output: DFA (D) (accepting the same language as N)
Method: The initial state of D is the set consist of Є-closure(S0), where S0 is the initial state
of N. Now the following steps will lead to D.

While there is an unmarked state x = {s1, s2,…………., sn} of D do


begin
mark x;
for each input symbol a do
begin
let T be the set of states to which there is a
transition on a from some state s, in x; y :=
Є-closure(T);
if y has not yet been added to the set of states of D then
make y an “unmarked” state of D;
add a transition from x to y labeled a if not already present
end
end

Now in the given example the initial state of N is 0 now starting with the state and moving
towards the DFA. We will first find out all the states of DFA by applying the algorithm and
then we will make a table and transition diagram of DFA.
0
Є-closure
0,1,2,4,7 A
a b

3,8 5
Є-closure
B 1,2,3,4,6,7,8 1,2,4,5,6,7 C
a b
b a

3,8 5,9 3,8 5


Є-closure
B 1,2,4,5,6,7,9 B C
a D
b
3,8 5,10
Є-closure
B 1,2,4,5,6,7,10 E

a b

3,8 5
Є-closure
B C
Transition Table:

States Input
a b
A B C
B B D
C B C
D B E
E B C
(Final State)

Transition Diagram:

a b

a B D
a

A b
a
a

E
b C
b

b
MINIMISATION OF DFA

The DFA produced form NFA have some states which can be removed without any
change to the functionality of the FA. To do this we the following method:

INPUT: A DFA M with set of states S inputs ∑ , transition defined on all states and
inputs, initial state S0 and set of final states F.

OUTPUT: A DFA M’ expecting the same language as M and having as few states as
possible.

METHOD: We construct a partition Π of set of final states, initially, Π consists of two


groups, the final states f and the non final states S-F then we construct a new partition Πnew
by the procedure that follows:
Πnew will always be a refinement of Π, meaning that Πnew consists of groups of Π, each
consists of one or more pieces, If Πnew is not equal to Π we replace the Π by Πnew and
repeat the below procedure. If Π = Πnew then no more changes can ever occur and so we
terminate this part of the algorithm.

For each group G of Π do


begin
Partition G into subgroups such that two states S and T of G are into same
subgroup if and only if for all I/P symbols a, states T and S have transitions to
states in the same group of Π.
Place all such groups in Πnew.

After getting the pairs we look for their representation i.e. if there is a group of more than
one state than it is represented by the initial and final state if any of them is present
otherwise any of the state can represent the whole group and even a new representation
can be formed.

Now taking example of the DFA we produced from NFA:


The transition table of that is:
States Input
a b
A B C
B B D
C B C
D B E
E B C
(Final State)
So the groups will be

A,B,C,D E
Subgroup Making

A,B,C D E
Subgroup Making

A,C B D E

Representing

A B D E

New Transition Table:

States Input
a b
A B A
B B D
D B E
E B A
(Final State)
New Transition Diagram:

a
a
b
B
A

b b
a
a

E D
b

You might also like