Deterministic Finite Automaton
Deterministic Finite automaton (DFA) is a machine that can recognize a regular language based on its grammar.
Components of DFA
Components
DFA has the following components,
- State set
- A vocabulary set
- A transition table
- A start state
- An accept state set
An automaton can take a symbol and transit to another state based on the transition function. That is, if , then we define,
We also define,
If a sentence satisfies,
Then we say that is accepted or recognized by the automaton.
We often illustrate with a graph, where each node represents a state, and an edge represents a transition, the label of the edge is the symbol that triggers the transition.
For example,
We add a to denote that the state is an accept state.
If we want this automaton to test , we would have the following process (the highted node is the current state), here is the example,
Example by Graph
Step 1: Start at q0
The automatonton begins in the start state q0, and the first symbol of the string is 0.
Step 2: Still in q0, next symbol is 0
The automatonton is still in q0, and it reads another 0, so it remains in q0.
Step 3: Now in q0, next symbol is 1
The automatonton now reads 1, so it transitions from q0 to q1 (accept state).
Final Step: End of input string, and state q1 is accepting
The DFA has finished reading all input symbols (001), and it has ended in q1, which is an accept state. Therefore, the string is accepted.
Example by Table
We can also just look after the table. Based on the same automaton, we have,
0 | 1 | |
---|---|---|
qs | qs | q1 |
q1* | q2 | q1 |
q2 | q2 | q2 |
Each element in the table is .
If we test ,
- Start at qs
- Read 0, go to qs
- Read 0, go to qs
- Read 1, go to q1
- String exhausted, and q1 is an accept state, so the string passes.
Minimizing a DFA
Sometimes, we may design a DFA that has more states than necessary, for example,
This automaton has the exact same function as the automaton above. For such simple cases, we can tell by eye. However, for more complex cases, we need a tool to minimize the automaton.
We define a pair of states is an equivalent pair if and only if they satisfy all the following conditions,
- They are both accept states or both not accept states.
- When accepting any symbol, they will transit to a pair of equivalent states.
If two states are equivalent, they can be merged into one.
We always use the most optimistic choice with circular decency. That is, if whether and are equivalent depends on wether and are equivalent, while and are dependent on and . Then we will always assume both of them are equivalent. This is also true for more circular dependencies.
We usually use a table called the equivalence table for help. We will demonstrate how to do it,
Let's consider,
Let's draw the table,
qs | B | C | D | E* | |
---|---|---|---|---|---|
qs | |||||
B | |||||
C | |||||
D | |||||
E* |
We ignore the half above the diagonal and the diagonal. Because the upper half is the exactly same as the lower half, and a state is always in pair with itself.
If we write in the element, then it means that the row and column are equivalent. If we write in the element, then it means that the row and column are not equivalent. If we write in the element, then it means that if the are equivalent, then the row and column are equivalent.
Let's construct the equivalence table. Because is the only end state, no other state is equivalent to . Therefore, we have,
qs | B | C | D | E* | |
---|---|---|---|---|---|
qs | |||||
B | |||||
C | |||||
D | |||||
E* | ❌ | ❌ | ❌ | ❌ |
We usually firstly fill as many obvious element as possible so that it makes our life a bit easier.
Then, we choose the ones that leads to the determined pairs (no matter whether they are equivalent or not), so that we can have most of the table filled with or .
Lastly, we iterate through all the remaining pairs.
Now we know is in no pair with any other state. Therefore, it'd be easier for us to consider the pairs in which an element points to .
For example, points to after , but for all other states, they don't go to after , and thus,
qs | B | C | D | E* | |
---|---|---|---|---|---|
qs | |||||
B | |||||
C | |||||
D | ❌ | ❌ | ❌ | ||
E* | ❌ | ❌ | ❌ | ❌ |
There are no obvious ones, so let's check the only three pairs remaining.
and : after , they both go to . After , goes to , and goes to . But and are not equivalent, so and are not equivalent.
and : after , they both go to . After , they both go to . Thus, and are equivalent.
and : after , goes to but goes to . and are not equivalent, so and are not equivalent.
In all,
qs | B | C | D | E* | |
---|---|---|---|---|---|
qs | |||||
B | ❌ | ||||
C | ✅ | ❌ | |||
D | ❌ | ❌ | ❌ | ||
E* | ❌ | ❌ | ❌ | ❌ |
We can simply redirect all lines pointing to to , then remove the node. In the transition table, we just replace all with .
This is a simple case.
We may have this type of table,
qs | F | G | H | |
---|---|---|---|---|
qs | ||||
F* | ❌ | |||
G* | ❌ | FH | ||
H* | ❌ | GH | FG |
There exists circular dependency. We use the most optimistic choice- as we said above, to get the table,
qs | F | G | H | |
---|---|---|---|---|
qs | ||||
F* | ❌ | |||
G* | ❌ | ✅ | ||
H* | ❌ | ✅ | ✅ |
This algorithm is an application of Hopcroft–Karp algorithm.
The Grammar of DFA
For a DFA, we can create a regular grammar that is equivalent to the DFA.
Suppose we have state set,
Then, we can create a regular grammar,
If , then,
So that using the regular grammar, we can generate the language of a DFA. Thus DFA generates regular language.
Please note that, by this conversion,
Can only exists one such rule. That is to say, is not allowed. So the grammar of DFA is actually a more restricted version of regular grammar.
NFA is actually directly corresponding to the regular grammar.