In the theory of computation, a language is a set of strings composed of alphabets. There are different categories of languages. Each category represents a set of computational problems. Commonly-known categories of languages are listed below:
One primitive category is regular languages.
A regular language is one that can be represented by a regular expression or finite automata.
A deterministic finite automata (DFA) is an abstract mathematical model composed of the following components:
It also contains a set of transition functions where each transition function is defined as:
where and . If we read while being at the state , the transition will take us to the state .
The language of the DFA is defined as the set of strings that can be accepted by the DFA. A string is considered an accepted string if a sequence of transition functions can lead from to one of the final states of the DFA by reading each character of the string from left to right. The acceptance can be notated using an extended transition function , as shown below:
Here, is a string composed of the characters of . The language comprises all strings for which .
A deterministic finite automata should fulfill the following characteristics:
A DFA is defined as a tuple ):
Let’s design DFAs for a few sample languages composed of different sets of alphabets.
Formally, the language will be described over as follows:
notates a combination of alphabets of any size including zero. For example, , and are members of because their length (number of characters) is odd.
To construct the deterministic finite automata for this language, we need to create two states. Each state is expected to take the responsibility of memorizing the odd and even lengths of the input. In other words, each of the states will be used to memorize , i.e. or . We don’t have any external memory in DFAs. Therefore, the limited amount of information can be hardwired in the states. For our convenience, we can label the states as and . With every new input character, the state will change from odd to even or even to odd. The resultant DFA will look like the one shown below:
Does the DFA above fulfill all the required characteristics of a DFA?
What will be the behavior of the DFA on the input () ?
What will be the behavior of the DFA on the input () ?
Formally, the language will be described over as follows:
The language contains strings like , , , , , etc.
There are two types of counters involved in the recognition of this language. After a transition, the number of s could be even or odd. Similarly, after a transition the number of s could be even or odd. At the start of the DFA recognizing this language, both of these counters will be even because the number of 's and the number of 's are zero at the start. In other words, the number of 's is even and the number of 's is even at the start state, i.e. . We have four such possible combinations that need to be modeled in the DFA. A combination with an even number of 's and an even number of 's will be represented by a state in the DFA notated as , where notates even and even. The first symbol in this notation represents the number of 's and the second symbol notates the number of 's. We model the DFA using this notation of the states and link them with the corresponding transitions as shown below.
What will be the behavior of the DFA above if we give the string () aba as an input to it?
What will be the behavior of the DFA on the input string () ba?
The language containing integers that are divisible by 3 can be formally described as follows over :
This language is composed of non-empty strings that can contain any digit from to . It’s given that any integer (which is a string made up of characters of ) can be a multiple of or not. When it’s a multiple of then the remainder will be zero. When the given string isn’t a multiple of then the possible remainder can be either or . Memorizing the remainders is important in this context. So, each state is expected to represent a possible remainder when the string consumed till that state is divided by . We label these states as , , and to represent the respective remainders. Additionally, we need to have a separate start state that will take us to either of the states notating a remainder.
For example, if the starting digit of the input is , , or then its remainder (when divided by ) is . These three possible input characters should take us to the state . When at state , if the next digit is , it makes up the string , , or , depending on what the first character was. When divided by , its remainder remains . That’s why the loop with the labels of these possible input characters keeps us in the same state. But if we read , or after the first character, the second character will be appended with the remainder computed so far, i.e. . So, the input string of two characters will be of the form , or . When divided by 3, it will take us to state because the remainder of all these combinations when divided by is . Similarly, if the second input character is , , or then the resultant becomes , , or after appending with the remainder . Because its remainder when divided by is , it takes us to state . This logic is replicated across all possible transitions from all the states.
Should the input () be accepted by the DFA? How will the DFA behave on it?
Should the input string () be accepted by the DFA? How will it behave on this input?
When is a string rejected by the DFA?
DFAs can be used to model many interesting real-world applications. Some examples are listed below:
We hope that you enjoyed this introduction to DFA. For an in-depth understanding of the theory of automata, you can explore the following:
Theory of Computation
What are the mathematics behind computers? What are the theoretical foundations of computer languages? Such questions can be explored by understanding formal languages and automata models. In this comprehensive course, you’ll explore formal languages, regular languages, and how to model them with their associated automata models. Next, you’ll cover regular expressions and grammar, and their equivalents. Then, you’ll explore context-free languages (the foundations of programming languages), pushdown automata, and the relationship between them. Toward the end, you’ll learn about recursively enumerable languages, Turing machines with their variations, context-sensitive languages, and unrestricted grammars. By the end of the course, you’ll have gained a deep understanding of several formal languages and their associated automata. Also, since there are plenty of exercises throughout the course, your understanding and problem-solving skills will be thoroughly reinforced.
Free Resources