CS402 — Final Term Summary (Lectures 23–45)
📘 Lecture 23 — Mealy machines in terms of sequential circuit
📖 Overview: This lecture demonstrates how a Mealy machine can be implemented using a sequential circuit composed of logic gates and a delay (flip-flop) box. It explains the step-by-step process of determining state transitions and outputs based on the circuit’s logical relationships, providing a concrete example with a transition table and diagram.
🗂️ Topics Covered
The lecture covers the components of a sequential circuit (NAND, DELAY, OR, AND boxes), the definition of four states based on current at points A and B, the transition rules for new A, new B, and output, and the construction of a transition table and diagram for the Mealy machine. It also includes an example of running a string through the machine to determine the output sequence.
📝 Lecture Summary
Example
The lecture presents a sequential circuit containing four types of boxes:
- NAND box (NOT AND): Provides the complement of the Boolean AND output for the given input.
- DELAY box (Flip Flop box): Delays the transmission of the signal along the wire by one step (clock pulse).
- OR box: Provides the Boolean OR output for the given input.
- AND box: Provides the Boolean AND output for the given input.
Current in the wire is indicated by 1, and 0 indicates the absence of current.
There are two points A and B with respect to which the following four states of the machine are identified according to the presence and absence of current at these points:
- q₀ (A=0, B=0) ≡ (0,0)
- q₁ (A=0, B=1) ≡ (0,1)
- q₂ (A=1, B=0) ≡ (1,0)
- q₃ (A=1, B=1) ≡ (1,1)
The operation of the circuit is such that the machine changes its state after reading 0 or 1. The transitions are determined using the following relations:
- new B = old A
- new A = (input) NAND (old A AND old B)
- output = (input) OR (old B)
🔑 Definition — old A and old B: These indicate the presence or absence of current at A and B before inputting any letter. Similarly, new A and new B indicate the presence or absence of current after reading a certain letter.
At various discrete pulses of a time clock, input is received by the machine and the corresponding output string is generated.
📌 Example: The transition at state q₀ after reading the letter 0 can be determined as follows:
- new B = old A = 0
- new A = (input) NAND (old A AND old B) = 0 NAND (0 AND 0) = 0 NAND 0 = 1
- output = (input) OR (old B) = 0 OR 0 = 0
Thus, after reading 0 at q₀, new B is 0 and new A is 1, so the machine moves to state (1,0) ≡ q₂, and during this process its output character is 0.
The remaining actions of this sequential circuit are shown in the following transition table of the corresponding Mealy machine:
| Old State | Inputting 0 | Inputting 1 |
|---|---|---|
| State | Output | |
| q₀ ≡ (0,0) | (1,0) ≡ q₂ | 0 |
| q₁ ≡ (0,1) | (1,0) ≡ q₂ | 1 |
| q₂ ≡ (1,0) | (1,1) ≡ q₃ | 0 |
| q₃ ≡ (1,1) | (1,1) ≡ q₃ | 1 |
💡 Why this matters: The transition table directly maps the sequential circuit’s behavior into a formal Mealy machine representation, which is essential for designing and analyzing digital systems.
The corresponding transition diagram is derived from the table (as shown in the lecture text).
📌 Example: Running the string 01101110 on the machine starting from state q₀ yields the following output sequence:
| Input | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| States | q₀ | q₂ | q₃ | q₁ | q₂ | q₃ | q₁ | q₂ |
| Output | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
🔑 Definition — Note: It may be noted that if the string 00 is read at any state, it results in ending in state q₃.
Note
It is to be noted that in this sequential circuit, the delay box plays an important role in introducing four states of the machine.
⭐ Key Takeaways
The four states of the machine (q₀ through q₃) are defined by the current at points A and B, which represent the outputs of the logic gates in the sequential circuit. The transition rules (new B = old A, new A = input NAND (old A AND old B), output = input OR old B) determine state changes and output for each input. The delay box is crucial as it introduces memory, creating the four distinct states. The transition table and diagram provide a complete Mealy machine representation of this circuit. Running a test string through the machine demonstrates how input sequences produce specific output sequences.
🧠 Quick Revision Questions
- What are the four types of boxes used in the sequential circuit, and what is the function of each?
- How are the four states (q₀, q₁, q₂, q₃) defined in terms of points A and B?
- Write down the three relations used to determine new B, new A, and output for a given input.
- What happens to the machine’s state and output when reading 0 at state q₀?
- If the string 00 is read at any state, which state does the machine end in?
📘 Lecture 24 — Regular Languages, Complement, and Intersection
📖 Overview: This lecture explores properties of regular languages, focusing on the closure properties under union, concatenation, and Kleene star, as well as proving that the complement and intersection of regular languages are also regular. It provides constructive proofs using regular expressions and TGs (Kleene’s theorem), which are essential for understanding language operations in automata theory.
🗂️ Topics Covered
Regular languages and their closure under union, concatenation, and Kleene star are reviewed. The complement of a language is defined, and a theorem proving that the complement of a regular language is regular is presented with an example using FA construction. Finally, the theorem that the intersection of two regular languages is regular is proved using De Morgan’s law and the complement closure property.
📝 Lecture Summary
Regular languages
As discussed earlier, any language that can be expressed by a RE is said to be a regular language. So if L₁ and L₂ are regular languages, then L₁ + L₂, L₁L₂, and L₁* are also regular languages. This fact can be proved by the following two methods.
🔑 Definition — Regular Language: Any language that can be expressed by a Regular Expression (RE) is called a regular language.
By Regular Expressions As discussed earlier, if r₁, r₂ are regular expressions corresponding to the languages L₁ and L₂, then the languages L₁ + L₂, L₁L₂, and L₁* generated by r₁ + r₂, r₁r₂, and r₁* are also regular languages.
By TGs (Transition Graphs) If L₁ and L₂ are regular languages, then L₁ and L₂ can also be expressed by some REs and hence, using Kleene’s theorem, L₁ and L₂ can also be expressed by some TGs.
- If L₁ and L₂ are expressed by TG₁ and TG₂, then a TG accepting L₁ + L₂ can be constructed by adding a new start state with λ-transitions to the start states of TG₁ and TG₂.
- A TG accepting L₁L₂ can be constructed by connecting each final state of TG₁ to the start state of TG₂ via a λ-transition, then making the old final states of TG₁ non-final and keeping the final states of TG₂.
- A TG accepting L₁* can be constructed by adding a new start state that is also a final state, with a λ-transition to the old start state, and adding λ-transitions from each old final state back to the old start state.
📌 Example: Consider the following TGs:
- TG₁ accepts language L₁ (strings with even number of a’s and b’s)
- TG₂ accepts language L₂ (strings with odd length)
Following may be a TG accepting L₁ + L₂, where a new start state connects to both original start states. A TG accepting L₁L₂ connects final states of TG₁ to start of TG₂. A TG accepting L₂* adds a new initial/final state with loops.
Complement of a language
Let L be a language defined over an alphabet Σ. Then the language of strings, defined over Σ, not belonging to L, is called the complement of the language L, denoted by Lᶜ or L’.
🔑 Definition — Complement of a Language: For a language L defined over alphabet Σ, Lᶜ = {w ∈ Σ* | w ∉ L}.
Note: To describe the complement of a language, it is very important to describe the alphabet of that language over which the language is defined. For a certain language L, the complement of Lᶜ is the given language L, i.e., (Lᶜ)ᶜ = L.
Theorem If L is a regular language, then Lᶜ is also a regular language.
Proof: Since L is a regular language, by Kleene’s theorem, there exists an FA, say F, accepting the language L. Converting each of the final states of F to non-final states and old non-final states of F to final states, the FA thus obtained will reject every string belonging to L and will accept every string, defined over Σ, not belonging to L. This shows that the new FA accepts the language Lᶜ. Hence, using Kleene’s theorem, Lᶜ can be expressed by some RE. Thus Lᶜ is regular.
💡 Why this matters: This provides a constructive method to build an FA for the complement of any regular language simply by toggling final and non-final states.
📌 Example: Let L be the language over the alphabet Σ = {a, b} consisting of only two words: aba and abb. The FA accepting L may have states: start → 1, 2, 3 (accepting), etc. Converting final states to non-final states and old non-final states to final states, the FA accepting Lᶜ now accepts all strings over Σ except "aba" and "abb".
Intersection of two regular languages
Theorem Statement: If L₁ and L₂ are two regular languages, then L₁ ∩ L₂ is also regular.
Proof: Using De Morgan’s law for sets: (L₁ᶜ ∪ L₂ᶜ)ᶜ = (L₁ᶜ)ᶜ ∩ (L₂ᶜ)ᶜ = L₁ ∩ L₂
Since L₁ and L₂ are regular languages, so are L₁ᶜ and L₂ᶜ (by the complement theorem). L₁ᶜ and L₂ᶜ being regular implies that L₁ᶜ ∪ L₂ᶜ is also a regular language (by closure under union). Therefore, (L₁ᶜ ∪ L₂ᶜ)ᶜ = L₁ ∩ L₂, being the complement of a regular language, is regular.
💡 Why this matters: This elegantly shows that the intersection of two regular languages is regular without needing to construct a new FA directly — it relies on already proven closure properties (union and complement).
⭐ Key Takeaways
Regular languages are closed under union (L₁+L₂), concatenation (L₁L₂), and Kleene star (L₁*), provable via both regular expressions and TG constructions. The complement of a regular language is regular, constructible by swapping final and non-final states in its FA. Using De Morgan’s law, the intersection of two regular languages is also regular, as it can be expressed as the complement of the union of their complements. These closure properties are fundamental for proving other language properties and for designing automata for complex languages without constructing them from scratch. Always define the alphabet when working with complements, as the complement depends entirely on the alphabet over which the language is defined.
🧠 Quick Revision Questions
- What are the two methods by which it can be proved that L₁+L₂, L₁L₂, and L₁* are regular if L₁ and L₂ are regular?
- Explain the step-by-step construction of a TG that accepts the complement of a language accepted by a given FA.
- Using De Morgan’s law, prove that the intersection of two regular languages L₁ and L₂ is also regular.
- Why is it essential to specify the alphabet when describing the complement of a language?
- Given an FA for language L that accepts strings of even length over {a, b}, how would you construct an FA for Lᶜ?
📘 Lecture 25 — Theory of Automata
📖 Overview: This lecture proves that the intersection of two regular languages is also regular, using De-Morgan's law. It then provides detailed examples of constructing finite automata for the intersection of regular languages, and concludes by introducing the concept of nonregular languages with a proof using the pumping lemma concept.
🗂️ Topics Covered
The lecture covers the theorem for intersection of two regular languages with its proof using De-Morgan's law, a remark on the difficulty of finding regular expressions for intersection, an example of finding an FA for the intersection of two languages (words with double a's and words with even number of a's), a short method for constructing FA for intersection, and the introduction of nonregular languages with the example of the language {aⁿbⁿ : n=0,1,2,3,...}.
📝 Lecture Summary
Theorem
Statement: If L₁ and L₂ are two regular languages, then L₁ ∩ L₂ is also regular.
Proof: Using De-Morgan's law for sets: (L₁ᶜ ∪ L₂ᶜ)ᶜ = (L₁ᶜ)ᶜ ∩ (L₂ᶜ)ᶜ = L₁ ∩ L₂
Since L₁ and L₂ are regular languages, so are L₁ᶜ and L₂ᶜ. L₁ᶜ and L₂ᶜ being regular provide that L₁ᶜ ∪ L₂ᶜ is also regular language and so (L₁ᶜ ∪ L₂ᶜ)ᶜ = L₁ ∩ L₂, being complement of regular language is regular language.
Remark: If L₁ and L₂ are regular languages, then these can be expressed by the corresponding FAs. Finding regular expressions defining the language L₁ ∩ L₂ is not so easy and building corresponding FA is rather harder.
Example
Consider two regular languages L₁ and L₂, defined over the alphabet Σ = {a, b}, where:
- L₁ = language of words with double a's
- L₂ = language of words containing even number of a's
FA₁ accepting L₁ has states p- (start), q, and r+ (final), with transitions: on 'a' from p→q and q→r; on 'b' from p→p, q→p, r→r.
FA₂ accepting L₂ has states 1± (start and final) and 2, with transitions: on 'a' from 1→2 and 2→1; on 'b' from 1→1 and 2→2.
Their corresponding REs may be:
- r₁ = (a+b)aa(a+b)
- r₂ = (b+aba)
Now FAs accepting L₁ᶜ and L₂ᶜ are constructed by swapping final and non-final states. FA₁ᶜ has states p± (start and final), q+ (final), and r; FA₂ᶜ has states 1± and 2.
An FA accepting L₁ᶜ ∪ L₂ᶜ is constructed using the product method with states being pairs from the two FAs:
Old States | New States after reading a | New States after reading b z₁±≡(p,1) | (q,2)≡z₄ | (p,1)≡z₁ z₂+≡(p,2) | (q,1)≡z₃ | (p,2)≡z₂ z₃+≡(q,1) | (r,2)≡z₆ | (p,1)≡z₁ z₄+≡(q,2) | (r,1)≡z₅ | (p,2)≡z₂ z₅≡(r,1) | (r,2)≡z₆ | (r,1)≡z₅ z₆+≡(r,2) | (r,1)≡z₅ | (r,2)≡z₆
An FA that accepts the language (L₁ᶜ ∪ L₂ᶜ)ᶜ = L₁ ∩ L₂ has states z₁- (start), z₂, z₃, z₄, z₅+ (final), z₆, with transitions on a and b as defined in the table.
The regular expression defining the language L₁ ∩ L₂ can be obtained by converting and reducing the FA into a GTG. After eliminating states z₂ and z₆, then z₃ and z₄, and eliminating loops, the required RE is: (b+abbab) a (a+bbaaba) (b+aba)
💡 Why this matters: This demonstrates that while intersection of regular languages is regular, constructing the actual FA and RE can be complex and requires systematic elimination of states.
FA corresponding to intersection of two regular languages (short method)
Let FA₃ be an FA accepting L₁ ∩ L₂, then the initial state of FA₃ must correspond to the initial state of FA₁ and the initial state of FA₂. Since the language corresponding to L₁ ∩ L₂ is the intersection of corresponding languages L₁ and L₂, consists of the strings belonging to both L₁ and L₂, therefore a final state of FA₃ must correspond to a final state of FA₁ and FA₂.
Example: Using the same FAs as above, the short method produces:
Old States | New States after reading a | New States after reading b z₁-≡(p,1) | (q,2)≡z₄ | (p,1)≡z₁ z₂≡(p,2) | (q,1)≡z₃ | (p,2)≡z₂ z₃≡(q,1) | (r,2)≡z₆ | (p,1)≡z₁ z₄≡(q,2) | (r,1)≡z₅ | (p,2)≡z₂ z₅+≡(r,1) | (r,2)≡z₆ | (r,1)≡z₅ z₆≡(r,2) | (r,1)≡z₅ | (r,2)≡z₆
The final state z₅+ corresponds to (r,1), where r is final in FA₁ and 1 is final in FA₂.
Nonregular Languages
The language that cannot be expressed by any regular expression is called a nonregular language. The languages PALINDROME and PRIME are the examples of nonregular languages.
🔑 Definition — Nonregular Language: A language that cannot be expressed by any regular expression, and by Kleene's theorem, cannot be accepted by any FA or TG.
Example: Consider the language L = {Λ, ab, aabb, aaabbb, ...} i.e. {aⁿbⁿ : n=0,1,2,3,...}
To prove that this language is nonregular, assume contrary that L is a regular language. Then by Kleene's theorem it must be accepted by an FA, say, F. Since every FA has finite number of states, the language L (being infinite) accepted by F must have words of length more than the number of states. This shows that F must contain a circuit.
For the sake of convenience, suppose F has 10 states. Consider the word a⁹b⁹ from the language L. Due to the finite number of states, the path traced by this word must contain a circuit. Looping the circuit generated by states 3,4,6,5,3 with a-edges once more, F also accepts the word a⁹⁺⁴b⁹ = a¹³b⁹, while a¹³b⁹ is not a word in L. Because of this circuit, F also accepts the words a⁹(a⁴)ᵐb⁹, m = 1,2,3,...
Moreover, there is another circuit generated by states 9,10,9. Including the possibility of looping this circuit, F accepts the words a⁹(a⁴)ᵐb⁹(b²)ⁿ where m,n=0,1,2,3,... (m and n not being 0 simultaneously). This shows that F accepts words that are not belonging to L.
📐 Formula: {aⁿbⁿ : n=0,1,2,3,...} — The language of equal numbers of a's followed by equal numbers of b's.
💡 Why this matters: This proof technique (pigeonhole principle applied to finite automata) shows that any FA with finite states cannot distinguish between strings that must have equal numbers, thus proving L is nonregular.
⭐ Key Takeaways
The intersection of two regular languages is always regular, proven using De-Morgan's law and the fact that regular languages are closed under complement and union. While the theorem guarantees regularity, constructing the actual FA and regular expression for the intersection is complex and involves the product construction method. The key insight is that the final states of the intersection FA must correspond to pairs where BOTH original FAs have final states. Nonregular languages like {aⁿbⁿ} cannot be accepted by any FA because any finite automaton with a limited number of states must contain circuits that allow it to accept strings with unequal numbers of a's and b's. The pumping lemma concept demonstrates that infinite regular languages must have repeating patterns (circuits), and languages requiring exact counting cannot be regular.
🧠 Quick Revision Questions
- How does De-Morgan's law help prove that the intersection of two regular languages is regular?
- In the example of L₁ (double a's) and L₂ (even number of a's), what is the final regular expression for L₁ ∩ L₂?
- In the short method for constructing FA for intersection, what condition determines whether a state (p,q) is a final state?
- Why does the existence of a circuit in an FA accepting {aⁿbⁿ} lead to a contradiction?
- What are the two circuits found in the FA that supposedly accepts {a⁹b⁹}, and what extra strings do they allow?
📘 Lecture 26 — Example of nonregular language, pumping lemma version I, proof, examples
📖 Overview: This lecture proves that the language {aⁿbⁿ} is nonregular using the pumping lemma. It formally states and proves the pumping lemma version I, which provides a necessary condition for infinite regular languages, and demonstrates its application through multiple examples including PALINDROME, revealing its limitations.
🗂️ Topics Covered
The lecture begins with a detailed example proving {aⁿbⁿ} is nonregular using the concept of finite state machine circuits. It then formally introduces the Pumping Lemma (version I) with its statement and proof. This is followed by worked examples applying the lemma to a 5-state FA and to {aⁿbⁿ} directly. The lecture also discusses the nonregularity of EQUAL language via closure properties and concludes with remarks on the pumping lemma's limitations, particularly regarding PALINDROME.
📝 Lecture Summary
Example
Consider the language L = {Λ, ab, aabb, aaabbb, ...} i.e. {aⁿ bⁿ : n=0,1,2,3,...}. Suppose it is required to prove that this language is nonregular. Let, contrary, L be a regular language then by Kleene's theorem it must be accepted by an FA, say, F. Since every FA has finite number of states then the language L (being infinite) accepted by F must have words of length more than the number of states. Which shows that, F must contain a circuit.
For the sake of convenience suppose that F has 10 states. Consider the word a⁹ b⁹ from the language L. But, looping the circuit generated by the states 3,4,6,5,3 with a-edges once more, F also accepts the word a⁹⁺⁴ b⁹, while a¹³b⁹ is not a word in L. Moreover, there is another circuit generated by the states 9,10,9. Including the possibility of looping this circuit, F accepts the words a⁹(a⁴)ᵐ b⁹(b²)ⁿ where m,n=0,1,2,3,... (m and n not being 0 simultaneously). Which shows that F accepts words that are not belonging to L. Similarly for finding FAs accepting other words from L, they will also accept the words which do not belong to L. Thus there is no FA which accepts the language L, which shows, by Kleene's theorem, that the language L can't be expressed by any regular expression.
💡 Why this matters: This example demonstrates that any FA accepting an infinite regular language must contain a circuit, and looping that circuit inevitably generates words outside the target language if the language is nonregular.
Pumping Lemma
Statement: Let L be any infinite regular language (that has infinite many words), defined over an alphabet Σ then there exist three strings x, y and z belonging to Σ* (where y is not the null string) such that all the strings of the form xyⁿz for n=1,2,3,... are the words in L.
Proof: If L is a regular language, then according to Kleene's theorem, there exists an FA, say, F that accepts this language. Now F, by definition, must have finite no of states while the language has infinitely many words, which shows that there is no restriction on the length of words in L, because if there were such restriction then the language would have finite many words.
Let w be a word in the language L, so that the length of word is greater than the number of states in F. In this case the path generated by the word w, is such that it cannot visit a new state for each letter i.e. there is a circuit in this path. The word w, in this case, may be divided into three parts:
- x: The substring which generates the path from initial state to the state which is revisited first while reading the word w. x can be a null string.
- y: The substring which generates the circuit starting from the state which was lead by x. y cannot be null string.
- z: The substring which is the remaining part of the word after y. This part may be null string as the word may end after y or z part may itself be a circuit.
Thus the word may be written as w = xyz where x,y and z are the strings, also y can't be a null string. Now this is obvious that, looping the circuit successively, the words xyyz, xyyyz, xyyyz,... will also be accepted by this FA i.e. xyⁿz, n=1,2,3,... will be words in L.
🔑 Definition — Pumping Lemma: For any infinite regular language L over alphabet Σ, there exist strings x, y, z ∈ Σ* with y ≠ Λ such that xyⁿz ∈ L for all n = 1, 2, 3, ...
🔑 Definition — Pumping: The process of looping a circuit in an FA to generate infinitely many words, effectively "pumping" the substring y to create new words of the form xyⁿz.
Example
Consider the following 5 states FA, say, F which accepts an infinite language. Let the word w = bbbababa, belonging to the language L, so that the length of word is greater than 6 (the number of states in F). In this case the path generated by this word is such that it cannot visit a new state for each letter i.e. there is a circuit in this path.
The state 2 is such that it is revisited first while reading the word w. So the word w can be decomposed, according to pumping lemma, as w = xyz = (b)(bba)(baba). If y-part of w is continuously pumped, the resulting strings will be accepted by F and hence will be words in the language accepted by F. Thus, by pumping lemma, the language accepted by F is regular.
📌 Example: w = bbbababa decomposed as x = b, y = bba, z = baba. Pumping y gives: b(bba)ⁿ(baba) for n = 1, 2, 3,... all accepted by F.
Remark: If the pumping lemma is applied directly on the language L = {aⁿ bⁿ : n=0,1,2,3,...}, it can be observed that for the word w = (aaa)(aaaabbbb)(bbb) where x = aaa, y = aaaabbbb and z = bbb. xyyz will contain as many number of a's as there are b's but this string will not belong to L because the substring ab can occur at the most once in the words of L, while the string xyyz contains the substring ab twice. On the other hand if y-part consisting of only a's or b's, then xyyz will contain number of a's different from number of b's. This shows that pumping lemma does not hold and hence the language is not regular.
Example
Consider the language EQUAL, of strings, defined over Σ={a,b}, with number of a's equal to number of b's, i.e. EQUAL = {Λ, ab, aabb, abab, baba, abba,...}. From the definition of EQUAL, it is clear that {aⁿ bⁿ} = a* b* ∩ EQUAL. Obviously a* b* defines a regular language while {aⁿ bⁿ} has been proved nonregular. Using the theorem that intersection of two regular languages is regular, it can be proved that the EQUAL is not regular. Because if it is considered regular then the language {aⁿ bⁿ} will, being intersection of regular languages, be regular language, which is impossible.
🔑 Definition — EQUAL: The language of strings over {a,b} with an equal number of a's and b's.
Remarks
In the previous examples, languages are proved to be regular or nonregular using pumping lemma. In fact to prove a certain language to be regular, it is not needed to use the full force of pumping lemma i.e. for a word with length greater than the number of states of the machine, decomposing the word into xyz and for a language to be regular it is sufficient that xyyz is in L. The condition that xyⁿz is in L for n>2, provides that the language is infinite.
Consider the language PALINDROME and a word w = aba belonging to PALINDROME. Decomposing w = xyz where x=a, y=b, z=a. It can be observed that the strings of the form xyⁿz for n=1,2,3,..., belong to PALINDROME. Which shows that the pumping lemma holds for the language PALINDROME (which is nonregular language). To overcome this drawback of pumping lemma, a revised version of pumping lemma is to be introduced.
💡 Why this matters: The PALINDROME example reveals a crucial limitation of pumping lemma version I — it provides a necessary condition for regularity but not a sufficient one. Some nonregular languages can still satisfy the lemma, requiring a stronger version for proof of nonregularity.
⭐ Key Takeaways
The pumping lemma version I states that for any infinite regular language L, there exist strings x, y (non-null), and z such that all strings xyⁿz for n ≥ 1 are in L. This lemma is proven by noting that any FA accepting an infinite language must have a circuit due to finite states, and the word can be decomposed into x (path to first revisited state), y (the circuit), and z (remainder). The language {aⁿbⁿ} is proved nonregular because any decomposition either produces strings with mismatched counts of a's and b's or with multiple occurrences of "ab", which are not in the language. EQUAL is also proved nonregular using closure under intersection with regular language ab. The pumping lemma has a limitation: nonregular languages like PALINDROME can satisfy it, motivating the need for a revised version.
🧠 Quick Revision Questions
- State the pumping lemma version I for infinite regular languages.
- Why must any FA accepting an infinite language contain a circuit?
- Using the pumping lemma, explain why {aⁿbⁿ} is not regular.
- How can the nonregularity of EQUAL be proved using closure properties?
- Why is PALINDROME considered a counterexample to the sufficiency of pumping lemma version I?
📘 Lecture 27 — Theory of Automata
📖 Overview: This lecture presents Pumping Lemma version II, a stronger version of the pumping lemma used to prove that certain languages are not regular. It also introduces the Myhill Nerode theorem, which provides a necessary and sufficient condition for a language to be regular based on the number of equivalence classes it generates over Σ*.
🗂️ Topics Covered
Pumping lemma version II statement and proof with examples including PALINDROME and PRIME languages, the concept of strings belonging to the same class in an FA, and the Myhill Nerode theorem with examples showing how regular languages generate a finite number of partition classes.
📝 Lecture Summary
Pumping Lemma version II
Statement — Let L be an infinite language accepted by a finite automaton with N states. Then for all words w in L that have length more than N, there are strings x, y, and z (y being non-null string) and length(x) + length(y) ≤ N such that w = xyz and all strings of the form xyⁿz are in L for n = 1, 2, 3, ...
The proof follows from the pigeonhole principle applied to the states visited while reading the first N characters of w. Since the FA has only N states, some state must repeat within the first N+1 steps, allowing us to identify the loop (y).
🔑 Definition — Pumping Lemma version II: A stronger version requiring that the pumping segment (xy) be within the first N characters of the word, where N is the number of states in the FA.
📌 Example — Consider the language PALINDROME, which is infinite. Suppose it is accepted by an FA with 78 states. Take the word w = a⁸⁵ba⁸⁵. Decompose w as xyz where y is non-null and length(x) + length(y) ≤ 78. This means xy consists only of a's (since the first 78 characters are a's). Then xyyz = a^(85+|y|)ba⁸⁵, which has more a's on the left than on the right. This string is NOT in PALINDROME because the first and last characters would be a, but the count imbalance breaks the palindrome property. Thus PALINDROME does not satisfy pumping lemma version II, proving PALINDROME is non-regular.
📌 Example — Consider the language PRIME = {a^p : p is prime}, defined over Σ = {a}. Assume PRIME is regular and accepted by an FA with 345 states. Choose w = a³⁴⁷ (347 is prime, length > 345). By pumping lemma, xyⁿz ∈ PRIME for n = 1, 2, 3, ... Let y = a^m where 1 ≤ m ≤ 345 (since length(x)+length(y) ≤ 345). Consider n = 348: xy³⁴⁸z = a³⁴⁷(a^m)³⁴⁷ = a^(347m + 347) = a^(347(m+1)). The exponent 347(m+1) is not prime for m = 1, 2, ..., 345 because 347(m+1) = 347 × (m+1), always having at least factors 347 and (m+1). When m+1 = 1 (m=0, but m≥1) or the product equals 347×1=347, but m+1≥2, so it's composite. Hence xy³⁴⁸z ∉ PRIME. Therefore PRIME is not regular.
💡 Why this matters: Version II is more restrictive than version I — the condition length(x)+length(y) ≤ N ensures the loop occurs early in the word, making it harder for non-regular languages to accidentally satisfy the lemma.
Strings belonging to same class
Consider a regular language L, defined over an alphabet Σ. If two strings x and y, defined over Σ, are run over an FA accepting L, then x and y are said to belong to the same class if they end in the same state, no matter whether that state is final or not.
🔑 Definition — Same class (w.r.t. an FA): Two strings belong to the same class if they lead the FA to the same state from the start state.
🔑 Note: This concept is equivalent to indistinguishability w.r.t. L. Strings x and y are in the same class if for all strings z, either both xz and yz belong to L or neither xz nor yz belongs to L.
Myhill Nerode theorem
Statement — For a language L defined over an alphabet Σ, L partitions Σ* into distinct classes (equivalence classes under the indistinguishability relation).
- If L is regular, then L generates a finite number of classes.
- If L generates a finite number of classes, then L is regular.
The proof follows from the fact that each class corresponds to a state in the minimal DFA for L.
📌 Example — Consider L = {strings over Σ={a,b} ending in a}. L partitions Σ* into two classes:
- C₁ = set of all strings ending in a (final state)
- C₂ = set of all strings not ending in a (non-final state)
Since there are finitely many (2) classes, L is regular. The FA accepting L has two states:
- C₂ (start, non-final) — on input a goes to C₁, on input b stays in C₂
- C₁ (final) — on input a stays in C₁, on input b goes to C₂
📌 Example — Consider L = {strings over Σ={a,b} containing double "aa"}. L partitions Σ* into three classes:
- C₁ = set of all strings without "aa" but ending in a
- C₂ = set of {Λ} and all strings without "aa" but ending in b
- C₃ = set of all strings containing "aa"
Since there are finitely many (3) classes, L is regular. The FA accepting L:
- C₂ (start, non-final) — on input a goes to C₁, on input b stays in C₂
- C₁ (non-final) — on input a goes to C₃ (found "aa"), on input b goes back to C₂
- C₃ (final) — on any input (a or b) stays in C₃
💡 Why this matters: The Myhill Nerode theorem gives both a necessary and sufficient condition for regularity, unlike the pumping lemma which only gives a necessary condition. If you can show infinitely many classes, the language is definitively non-regular.
⭐ Key Takeaways
The pumping lemma version II requires that the pumping segment xy be within the first N characters (where N is the number of states), making it more powerful than version I for proving non-regularity. Languages like PALINDROME and PRIME fail version II, confirming their non-regularity. The Myhill Nerode theorem establishes that a language is regular if and only if it partitions Σ* into a finite number of equivalence classes under the indistinguishability relation. These classes correspond directly to the states of the minimal DFA accepting the language. This theorem is the most definitive test for regularity, as it provides both necessary and sufficient conditions.
🧠 Quick Revision Questions
- What is the difference between Pumping Lemma version I and version II regarding the length constraint?
- Why does the word a⁸⁵ba⁸⁵ in the PALINDROME example fail the pumping lemma version II when decomposed within the first 78 characters?
- In the PRIME example, why does the exponent 347(m+1) not remain prime for any m = 1, 2, ..., 345?
- According to the Myhill Nerode theorem, how many equivalence classes does the language L = {strings ending in "ab"} over Σ={a,b} generate? Construct the corresponding FA.
- What is the relationship between "strings belonging to the same class" (w.r.t. an FA) and "indistinguishable strings w.r.t. L"?
📘 Lecture 28 — Examples of Myhill Nerode theorem, Quotient of a language, examples, Pseudo theorem: Quotient of a language is regular, prefixes of a language, example
📖 Overview: This lecture continues the application of the Myhill Nerode theorem by demonstrating how languages partition Σ* into distinct classes, proving regularity. It then introduces the concept of the quotient of two languages and examines a pseudo theorem claiming the quotient of regular languages is regular, providing a counterexample. Finally, the lecture defines and illustrates the prefixes of a language in another language.
🗂️ Topics Covered
The lecture covers detailed examples of the Myhill Nerode theorem for the EVEN-EVEN language and a language ending in ab or ba, illustrating how partitions of Σ* lead to Finite Automata. It then defines the quotient of a language into another, introduces and disproves a pseudo theorem about the regularity of the quotient, and concludes with the definition and example of prefixes of a language in another language.
📝 Lecture Summary
Example
Consider the language L which is EVEN-EVEN, defined over Σ = {a,b}. It can be observed that L partitions Σ* into the following four classes: C1 = set of all strings with even number of a’s and odd number of b’s. C2 = set of all strings with odd number of a’s and odd number of b’s. C3 = set of all strings with odd number of a’s and even number of b’s. C4 = set of all strings with even number of a’s and even number of b’s.
Since there are finite many classes generated by L, so L is regular and hence following is an FA, built with the help of C1, C2, C3 and C4, accepting L.
[An FA diagram is provided in the original text with states c1, c2, c3, c4 and transitions labeled a and b.]
Example
Consider the language L = {w ∈ {a,b}: length(w) ≥ 2, w ends in either ab or ba}. It can be observed that L partitions Σ into the following seven classes: C1 = set containing only null string. C2 = set containing only letter a. C3 = set containing only letter b. C4 = set of strings ending in aa. C5 = set of strings ending in ab. C6 = set of strings ending in ba. C7 = set of strings ending in bb.
Since there are finite many classes generated by L, so L is regular and hence the FA shown aside, is built with the help of C1, C2, C3, C4, C5, C6 and C7, accepting L.
Following is an FA equivalent to the above FA:
[An FA diagram is provided in the original text with states 1-, 2+, 3, 4+, 5+ and transitions labeled a and b.]
Note: It can be noted, from the above two FAs accepting the same language, that if the language L, partitions Σ* into n distinct classes, then L may partition Σ* into finite many distinct classes other than n.
Quotient of a language into another
Remark: The theorem has been proved to show under what conditions a language is regular. It has also been proved that the product of two regular languages is regular. The question arises that whether there exists a theorem showing that quotient of regular languages is regular.
There is a problem in defining the quotient of two regular languages. There is an approach in defining the quotient of regular languages i.e. the language Q is said to be quotient of two regular languages P and R, denoted by Q=R/P if PQ=R. It is to be noted that this definition does not determine a unique language e.g. for P=Q=R expressed by a* then PQ=R and so Q=R/P i.e. a*=a* / a*. But for Q={Λ}, P=R expressed by a*, PQ=R is still true which shows that Q={Λ}=R/P expressed by a* / a*.
Similarly, for the same P and R, Q may be taken as {Λ},{a},{aaaa},{aaaaaaaa}, ... Thus there exist infinite many choices for defining the quotient language in this case of one-letter alphabet.
Pseudo theorem
Statement: For three languages P,Q and R, while PQ=R the language Q must be regular if both P and R are regular. (Note: It is to be noted that since this theorem is not true, so the theorem is called pseudo theorem.)
Disproof: The theorem can be disproved by contradiction i.e. supposing that Q is regular.
Let P=a*, Q be the product of {aⁿbⁿ:n=0,1,2,...} and b* then PQ=a*{aⁿbⁿ}b*=ab=R which shows that R is regular. To disproof this theorem, it is sufficient to prove that Q is not regular. By definition, the words in Q are of the form aˣbʸ where x ≤ y. Let Q be regular and hence there exists an FA that accepts Q. Suppose the number of states in this machine be N. Now the word aᴺbᴺ is also in Q and must be accepted by this FA.
Since the number of states in this machine is N, there must be a circuit in this machine to run the substring aᴺ. Thus while accepting the word aᴺbᴺ, the machine looping the circuit once again, can accept the word a^(more than N)bᴺ, which is not in Q. Hence it is impossible to find any FA that accepts exactly the language Q. Thus Q is not regular and hence the theorem is disproved.
🔑 Definition — Pseudo Theorem: A statement that is claimed to be a theorem but is actually false; in this context, the false claim that for three languages P, Q, and R, if PQ=R and P and R are regular, then Q must be regular. 📐 Logic of Disproof: Let P=a*, Q={aⁿbⁿ}b*, and R=ab. Since PQ=a*{aⁿbⁿ}b*=ab=R, R is regular. However, Q contains words of the form aˣbʸ with x ≤ y, which is known to be non-regular (pumping lemma). Therefore, the theorem is false. 💡 Why this matters: This pseudo theorem demonstrates a critical pitfall in automata theory: the quotient of two regular languages is not necessarily regular, contradicting a plausible but incorrect assumption.
Prefixes of a language in another language
If two languages R and Q are given, then the language the prefixes of Q in R denoted by Pref(Q in R) is the set of strings of letters that, when concatenated to the front of some word in Q to produce some word in R i.e. Pref(Q in R) = the set of all strings p such that there exists words q in Q and w in R such that pq = w.
Following are the examples in this regard:
Example: Let Q = {aa,abaaabb,bbaaaaa,bbbbbbbbbb} and R = {b,bbbb,bbbaaa,bbbaaaaa}. It can be observed that aa and bbaaaaa occur at the ending parts of some words of R, hence these words help in defining the language pref(Q in R). Thus pref(Q in R) = {b,bbba,bbbaaa}.
Note: The language of prefixes may be consisting of word L, while there is also a possibility that this language may not contain any string (even not the null string).
🔑 Definition — Pref(Q in R) (prefixes of Q in R): The set of all strings p such that there exist words q in Q and w in R where pq = w. In other words, p is a string that, when appended to the front of some word from Q, produces a word from R. 📌 Example: Given Q={aa, abaaabb, bbaaaaa, bbbbbbbbbb} and R={b, bbbb, bbbaaa, bbbaaaaa}, we find:
- b (from R) can be formed by p=b and q=Λ (null string) if Λ were in Q, but more directly, p=bbba and q=-aa? Actually, the example states: "aa and bbaaaaa occur at the ending parts of some words of R". For word "bbbaaa" in R, we see p=bbba and q=aa producing bbbaaa. For word "bbbaaaaa", we see p=bbba and q=aaaa? No, the example states pref(Q in R) = {b, bbba, bbbaaa}. So p=b may come from p=b and q=bbbb (if bbbbb were in Q—wait, the example needs careful parsing). The core idea is: pref(Q in R) = the strings that are prefixes of R that, when followed by a word from Q, give R. The answer is {b, bbba, bbbaaa}.
⭐ Key Takeaways
The Myhill Nerode theorem provides a powerful method to prove regularity by showing a language partitions Σ* into a finite number of equivalence classes, which directly corresponds to the number of states in a minimal FA. The quotient of two languages, defined as Q=R/P when PQ=R, is problematic because it does not yield a unique language, and a natural-sounding theorem claiming the quotient of regular languages is regular is actually a pseudo theorem, as demonstrated by a counterexample using the non-regular language {aⁿbⁿ}. The concept of prefixes of a language in another language, Pref(Q in R), isolates the set of strings that can serve as a prefix to a word in Q to form a word in R, which is a useful linguistic operation.
🧠 Quick Revision Questions
- For the EVEN-EVEN language, how many equivalence classes does the Myhill Nerode theorem produce over Σ={a,b}, and what characterizes each class?
- In the example of the language ending in ab or ba, why does the partition of Σ* into 7 classes prove the language is regular, and how does the number of classes relate to the FA states?
- Why is the definition of quotient Q=R/P not unique, and what does this ambiguity imply for the pseudo theorem about regularity?
- Describe the exact counterexample used to disprove the pseudo theorem: what are P, Q, and R, and how does the pumping lemma for regular languages show Q is not regular?
- Given languages Q and R, how is Pref(Q in R) defined, and what does the set {b, bbba, bbbaaa} from the example tell us about the relationship between Q and R?
📘 Lecture 29 — Theory of Automata
📖 Overview: This lecture explores the concept of prefixes of a language relative to another language, proving that pref(Q in R) is regular when R is regular. It then introduces decidability, decision procedures, and methods for determining whether two regular languages are equivalent or whether a given FA accepts any words.
🗂️ Topics Covered
The lecture begins with an example of prefixes of a language (pref(Q in R)), followed by a theorem proving that pref(Q in R) is regular if R is regular, with a proof and example. It then covers decidability, effectively solvable problems, and decision procedures. The lecture concludes with two methods for determining whether two languages are regular and equivalent, including examples and a method to test whether an FA accepts any words.
📝 Lecture Summary
Example of prefixes of a language
Let Q and R be expressed by ab*a and (ba)* respectively, i.e. Q = {aa, aba, abba, ...} and R = {Λ, ba, baba, bababa, ...}. aba is the only word in Q which can make a word in R, because the words in R don't contain the double letter. Thus pref(Q in R) = {b, bab, babab, ...}, which can be expressed by b(ab)* or *(ba)b.
💡 Why this matters: The language R cannot be factorized with the help of language Pref(Q in R) i.e. Pref(Q in R)Q is not equal to R in general. However, the following theorem shows that the language pref(Q in R) is regular if R is regular, no matter whether the language Q is regular or not.
Theorem: pref(Q in R) is regular
Statement: If R is regular language and Q is any language (regular/nonregular), then Pref(Q in R) is regular.
Proof: Since R is regular, there exists an FA that accepts this language. Choose a state, say, s of this FA and see whether this state can trace out a path ending up in a final state while running words from Q. If this state traces out a path ending up in a final state for any of the words of Q, mark this state with certain colour. Repeat this process for remaining states of the machine. If at least one state of this machine is marked then it can be shown that the language Pref(Q in R) is non-empty. Now build a new FA with some marked states by considering the initial state that of original FA and final states which are marked. The machine, thus obtained accepts exactly the language Pref(Q in R). Thus Pref(Q in R) being accepted by an FA is regular.
Remark: There is a problem in deciding whether a state of FA should be marked or not when the language Q is infinite. This proof just gives non-constructive method to prove that Pref(Q in R) is regular.
Example of the theorem
Consider the languages Q = {aba, abb} and R = {w ∈ {a,b}* : length(w) ≥ 2, w ends in either ab or ba}, where R may be accepted by the following FA:
[FA diagram with states 1– (initial), 2, 3, 4+, 5+ connected by edges labeled a and b]
It can be observed that the string aba from Q makes the words of R and hence the states 1, 2, 3, 4 and 5 can easily be marked. Thus from the given FA, making the states 1, 2 and 3 to be final as well, the resulting FA will accept the language pref(Q in R). Moreover it can be observed that pref(Q in R) can be expressed by (a+b)*, which is the RE corresponding to the resulting FA as well.
Decidability
Effectively solvable problem: A problem is said to be effectively solvable if there exists an algorithm that provides the solution in finite number of steps e.g. finding solution for quadratic equation is effectively solvable problem, because the quadratic formula provides an algorithm that determines the solution in a finite number of arithmetic operations, (four multiplications, two subtractions, one square root and one division).
🔑 Definition — Decision procedure: If an effectively solvable problem has answer in yes or no, then this solution is called decision procedure.
🔑 Definition — Decidable problem: A problem that has decision procedure is called decidable problem e.g. the following problems:
- The two regular expressions define the same language
- The two FAs are equivalent
Determining whether the two languages are equivalent or not
If L₁ and L₂ are two regular languages, then they can be expressed by FAs. As shown earlier, L₁ᶜ, L₂ᶜ, L₁ ∪ L₂, L₁ ∩ L₂ are regular languages and the methods have already been developed to build their corresponding FAs. It can be observed that (L₁ ∩ L₂ᶜ) ∪ (L₁ᶜ ∩ L₂) is regular language that accepts the words which are in L₁ but not in L₂ or else in L₂ but not in L₁. The corresponding FA cannot accept any word which is in both L₁ and L₂ i.e. if L₁ and L₂ are equivalent, then this FA accepts not even null string.
Method 1 for testing equivalence
For FA corresponding to (L₁ ∩ L₂ᶜ) ∪ (L₁ᶜ ∩ L₂), the regular expression can be determined that defines the language accepted by this FA. From that regular expression one can determine whether this regular expression defines any word or not. Following are the steps to be followed:
- Remove all *s from the regular expression
- Separate the right part of + and the plus itself
The regular expression thus obtained if contains at least one word then the language is not empty otherwise the language is empty.
Example: For (a+Λ)(ab+ba)(a+Λ)** to be the regular expression of (L₁ ∩ L₂ᶜ) ∪ (L₁ᶜ ∩ L₂), it is required to find whether this language accepts any string or not?
After removing all *s the RE will be (a+Λ)(ab+ba)(a+Λ). After separating the right part from + and the + itself the RE will be aaba. As this language contains at least aaba as its word, so this language is not empty.
Remark: Sometimes, while determining regular expression for a given FA, it is impossible to write its regular expression e.g. FA₁, FA₂, FA₃ [diagrams shown].
Method 2 for testing whether FA accepts any words
To examine whether a certain FA accepts any words, it is required to seek the paths from initial to final state. But in large FA with thousands of states and millions of directed edges, without an effective procedure it is impossible to find a path from initial to final state. Following are the steps of this procedure:
- Mark the initial state
- For every marked state, follow each edge that leads out of it and mark the concatenating states and delete these edges
- Repeat step 2 until no new state is marked
- If any of the final states are marked then the FA accepts some word, otherwise not
Example: Suppose it is required to test the FA [diagram with states 1–, 2, 3, 4, 5, 6+, edges labeled a and b], whether it accepts any string or not? Applying method 2:
[Step-by-step application of method 2 shown on the FA diagram]
This FA accepts no string as after applying method 2, the final state (6+) is not marked.
⭐ Key Takeaways
The most critical points to remember are: (1) Pref(Q in R) is regular whenever R is regular, regardless of whether Q is regular or not — this is proven by marking states in the FA for R that can trace paths to final states using words from Q. (2) A decidable problem has a decision procedure (yes/no answer) that can be completed in finite steps. (3) To determine if two regular languages L₁ and L₂ are equivalent, construct an FA for (L₁ ∩ L₂ᶜ) ∪ (L₁ᶜ ∩ L₂) and test whether it accepts any words — if it accepts no words (not even null), the languages are equivalent. (4) Method 1 for testing emptiness involves removing *s and + from the regular expression and checking if any word remains. (5) Method 2 for testing whether an FA accepts any words involves marking the initial state, following edges to mark new states while deleting used edges, and checking if any final state gets marked — if not, the FA accepts no words.
🧠 Quick Revision Questions
- What is the language Pref(Q in R)? Give an example where Q = {aba, abb} and R = words ending in ab or ba with length ≥ 2.
- State and prove the theorem that Pref(Q in R) is regular when R is regular.
- What is the difference between an effectively solvable problem and a decidable problem? Give one example of each.
- Describe Method 1 for determining whether two regular languages L₁ and L₂ are equivalent. What does the regular expression (a+Λ)(ab+ba)(a*+Λ)* become after removing *s and +?
- Describe Method 2 for testing whether an FA accepts any words. Explain why the final state must be marked for the FA to accept any string.
📘 Lecture 30 — Deciding Equivalence of Languages, Acceptance, and Finiteness
📖 Overview: This lecture covers procedures for deciding whether two regular languages are equivalent, whether a finite automaton accepts any string, and whether a language is finite or infinite. These are fundamental decision problems in automata theory with practical applications in compiler design and verification.
🗂️ Topics Covered
The lecture covers deciding whether two languages are equivalent using a complement-intersection method with detailed examples, determining whether an FA accepts any string using three different methods including marking states and testing words of length less than N, and deciding finiteness of a regular language using the pumping lemma theorem relating to word lengths between N and 2N.
📝 Lecture Summary
Example (Equivalence of Languages)
Consider two languages L₁ and L₂ expressed by the regular expressions r₁ = a* and r₂ = Λ + aa* respectively. To determine whether L₁ and L₂ are equivalent, we construct FAs for the languages and then find the FA corresponding to (L₁ ∩ L₂ᶜ) ∪ (L₁ᶜ ∩ L₂). If this FA accepts any word, then L₁ and L₂ are not equivalent; otherwise they are equivalent.
Following are the FAs corresponding to L₁ᶜ and L₂ᶜ:
- FA₁ᶜ: starts at s₁-, goes to s₂+ on a, s₃ on b
- FA₂ᶜ: starts at s₁-, goes to s₂ on a, s₃ on b
FAs corresponding to (FA₁ᶜ ∩ FA₂)ᶜ and (FA₂ᶜ ∩ FA₁)ᶜ are then constructed:
- (FA₁ᶜ ∩ FA₂)ᶜ: states (q₁,r₃), (q₁,r₁)-, (q₂,r₂) with transitions on a and b
- (FA₂ᶜ ∩ FA₁)ᶜ: states (p₁,s₃), (p₁,s₁)-, (p₂,s₂) with transitions on a and b
Both FAs have no final state, so they accept nothing. This implies their union will also not accept any string. Hence the FA corresponding to (L₁ ∩ L₂ᶜ) ∪ (L₁ᶜ ∩ L₂) accepts nothing. Thus both languages are equivalent.
Example (Deciding if FA Accepts Any String)
Another example shows an FA for which we decide whether it accepts any string using method 2 (marking states). The process involves marking the start state, then iteratively marking states reachable from marked states via input strings. Since no final state of the FA is marked, the given FA accepts no word.
🔑 Definition — Effective Procedure: A method that is guaranteed to produce a correct answer in finite time for any input of a given class.
Method 3
If the FA has N states, then test the words of length less than N. If no word is accepted by this FA, then it will accept no word.
📐 Formula: Test all strings of length < N states → If none accepted, language is empty.
💡 Why this matters: This provides a guaranteed finite procedure to check emptiness of a regular language.
Example (Method 3)
To determine whether the following FA accepts certain word, using method 3, all strings of length less than 4 (i.e. less than the number of states of the FA) are sufficient to be tested.
The strings to test: Λ, a, b, aa, ab, ba, bb, aaa, aab, aba, abb, baa, bab, bba, bbb
It can be observed that the strings aa, baa, aaa are accepted by this FA, hence the language accepted by this FA is not empty.
Example (Empty Language via Method 3)
Consider another FA. To determine whether this FA accepts some word, all strings of length less than 4 are to be tested.
It can be observed that none of the strings Λ, a, b, aa, ab, ba, bb, aaa, aab, aba, abb, baa, bab, bba, bbb is accepted by this FA. Thus the given FA cannot accept any word.
Observation (Infinite Language)
To find whether a regular expression defines an infinite language or not, the following possibilities are required to be checked. If a regular expression contains * then it may define an infinite language, with the exception Λ* as Λ* = Λ. For example: (Λ + aΛ*)(Λ* + Λ)* defines a finite language, while (Λ* + aΛ*)(Λ + Λ)* defines an infinite language.
Theorem
Let F be an FA having N states.
- If F accepts a word w such that N ≤ length(w) < 2N, then F accepts infinite language.
- If F accepts an infinite language, then there are some words w such that N ≤ length(w) < 2N.
The first part can be proved using the pumping lemma version II.
📐 Formula: Number of strings to test = m^N + m^(N+1) + m^(N+2) + ... + m^(2N-1), where m = alphabet size
📌 Example: For machine of 3 states and alphabet of 2 letters, 2³ + 2⁴ + 2⁵ = 56 strings are to be tested.
⭐ Key Takeaways
The most critical concepts to remember are: two languages are equivalent if their symmetric difference accepts no words, which can be checked using complement-intersection construction. To determine if an FA accepts any string, you can use the marking method or test all strings of length less than the number of states — if none are accepted, the language is empty. The finiteness of a regular language can be decided by testing all words of length between N and 2N-1 (inclusive) — if any such word is accepted, the language is infinite. A regular expression containing * may define an infinite language, but with exceptions like Λ*. All these methods are effective procedures guaranteed to terminate in finite time.
🧠 Quick Revision Questions
- How do you construct an FA to test whether two regular languages L₁ and L₂ are equivalent?
- If an FA has 5 states, what is the maximum length of strings that need to be tested to decide if it accepts any word (using method 3)?
- What condition on word length determines whether a language accepted by an FA with N states is infinite?
- Give an example of a regular expression containing * that defines a finite language.
- How many strings must be tested for an FA with 4 states over an alphabet of 3 letters to decide finiteness?
📘 Lecture 31 — Context Free Grammar, Terminals, Non-Terminals, Productions, CFG, Context Free Language, Examples
📖 Overview: This lecture introduces context free grammar (CFG) as a formal method for defining programming languages, explaining the difference between syntactic and semantic rules. It defines the core components — terminals, non-terminals, and productions — and illustrates how CFGs generate context free languages through multiple examples.
🗂️ Topics Covered
The lecture covers the historical need for CFGs in compiler design, the distinction between semantics and syntactics, CFG terminologies (terminals, non-terminals, productions), the formal definition of CFG, and context free language (CFL) with several examples showing how different grammars can generate the same language (a* and (a+b)*).
📝 Lecture Summary
Context Free Grammar (CFG)
The earliest computers accepted only assembly language instructions (LOAD, STORE, ADD). A major problem was displaying mathematical formulas like S = (1/2+9)/(4+8/21+5/(3+1/2)) in one line using standard typewriter symbols, requiring parentheses such as ((1/2)+9)/(4+(8/21)+(5/(3+(1/2)))). This led to high-level languages, which are converted into assembly language by a program called a compiler. The compiler takes user programs as input and prints an equivalent assembly language program.
Like spoken languages, high-level computer languages have grammar. The grammatical rules that involve word meaning are called Semantics, while rules that do not involve meaning are called Syntactics. For example, in English "Buildings sing" is invalid due to semantics, but in computer language one number is as good as another (e.g., X = B + 10 or X = B + 999).
💡 Why this matters: In general, computer language grammar rules are all syntactic and not semantic. A law of grammar is in reality a suggestion for possible substitutions.
CFG terminologies
Terminals: The symbols that can’t be replaced by anything are called terminals.
Non-Terminals: The symbols that must be replaced by other things are called non-terminals.
Productions: The grammatical rules are often called productions.
CFG
CFG is a collection of the following:
- An alphabet Σ of letters called terminals from which the strings are formed, that will be the words of the language.
- A set of symbols called non-terminals, one of which is S, stands for "start here".
- A finite set of productions of the form: non-terminal → finite string of terminals and/or non-terminals.
🔑 Definition — Terminals: designated by small letters; Non-terminals: designated by capital letters.
📌 Note: There is at least one production that has the non-terminal S as its left side.
Context Free Language (CFL)
The language generated by CFG is called Context Free Language (CFL).
Example — a using S → aS, S → Λ* Σ = {a} Productions: S → aS, S → Λ
Applying production (1) six times and then production (2) once, the word aaaaaa is generated as: S ⇒ aS ⇒ aaS ⇒ aaaS ⇒ aaaaS ⇒ aaaaaS ⇒ aaaaaaS ⇒ aaaaaaΛ = aaaaaa
It can be observed that production (2) generates Λ, a can be generated applying production (1) once then production (2), aa by applying production (1) twice then production (2), and so on. This shows the grammar defines the language expressed by a*.
Example — a using S → SS, S → a, S → Λ* Σ = {a} Productions: S → SS, S → a, S → Λ
This grammar also defines the language expressed by a*.
🔑 Definition — Λ (lambda): Λ is not considered to be terminal. It has a special status. If for a certain non-terminal N, there may be a production N → Λ, this simply means that N can be deleted when it comes in the working string.
Example — (a+b) using X, Y approach* Σ = {a,b} Productions: S → X, S → Y, X → Λ, Y → aY, Y → bY, Y → a, Y → b
All words of this language are of either X-type or Y-type. i.e., while generating a word the first production used is S → X or S → Y. The words of X-type give only Λ, while the words of Y-type are words of finite strings of a’s or b’s or both i.e. (a+b)⁺. Thus the language defined is expressed by (a+b)*.
Example — (a+b) using direct productions* Σ = {a,b} Productions: S → aS, S → bS, S → a, S → b, S → Λ
This grammar also defines the language expressed by (a+b)*.
Example — (a+b)aa(a+b) Σ = {a,b} Productions: S → XaaX, X → aX, X → bX, X → Λ
This grammar defines the language expressed by (a+b)aa(a+b).
⭐ Key Takeaways
CFG consists of terminals (symbols that cannot be replaced), non-terminals (symbols that must be replaced, with S as the start), and productions (rules of the form non-terminal → string of terminals/non-terminals). The language generated by a CFG is called a Context Free Language (CFL). Λ has a special status as a non-terminal that can be deleted from the working string, and different CFG productions can generate the same language (e.g., multiple grammars for a* and (a+b)*). Remember that terminals are designated by small letters and non-terminals by capital letters, and at least one production must have S on the left side.
🧠 Quick Revision Questions
- What are the three essential components of a Context Free Grammar?
- How is Λ different from a terminal symbol in CFG?
- Show two different CFGs that both generate the language a*.
- What is the distinction between semantics and syntactics in computer language grammar?
- What language does the CFG with productions S → XaaX, X → aX, X → bX, X → Λ generate?
📘 Lecture 32 — Examples of CFL, EVEN-EVEN, EQUAL, Language of strings containing bbb, PALINDROME, {a^n b^n}, Language of strings beginning and ending in different letters, Parsing tree, example
📖 Overview: This lecture provides multiple detailed examples of Context-Free Grammars (CFGs) for various important languages, including EVEN-EVEN, EQUAL, strings containing bbb, PALINDROME, {a^n b^n}, and strings beginning and ending in different letters. It also introduces the concept of the parse tree (or derivation tree) as a visual representation of how a word is generated by a grammar, which is critical for understanding syntax analysis.
🗂️ Topics Covered
The lecture presents and analyzes six distinct CFG examples: the EVEN-EVEN language, the EQUAL language, the language of strings containing bbb, PALINDROME, the language {a^n b^n}, and the language of strings beginning and ending in different letters. The final topic introduces the construction and purpose of a parsing tree (syntax/derivation tree) using the word "baab".
📝 Lecture Summary
Examples of CFL, EVEN-EVEN, EQUAL, Language of strings containing bbb, PALINDROME, {a^n b^n}, Language of strings beginning and ending in different letters, Parsing tree, example
Example
Σ = {a,b} productions: S → SS S → XS S → Λ S → YSY X → aa X → bb Y → ab Y → ba This grammar generates the EVEN-EVEN language.
Example
Σ = {a,b} productions: S → aB S → bA A → a A → aS A → bAA B → b B → bS B → aBB This grammar generates the language EQUAL (the language of strings, with number of a’s equal to number of b’s).
Note
It is to be noted that if the same non-terminal has more than one production, it can be written in a single line e.g. S → aS, S → bS, S → Λ can be written as S → aS|bS|Λ. It may also be noted that the productions S → SS|Λ always defines the language which is closed w.r.t. concatenation i.e. the language expressed by RE of type r*. It may also be noted that the production S → SS defines the language expressed by r^+.
Example
Σ = {a,b} productions: S → YXY Y → aY|bY|Λ X → bbb It can be observed that, using prod.2, Y generates Λ. Y generates a. Y generates b. Y also generates all the combinations of a and b. Thus Y generates the strings generated by (a+b)*. It may also be observed that the above CFG generates the language expressed by (a+b)*bbb(a+b)*. Following are four words generated by the given CFG
S ⇒ YXY ⇒ aYbbbΛ ⇒ abYbbb ⇒ abΛbbb = abbbb
S ⇒ YXY ⇒ bYbbbaY ⇒ bΛbbbabY ⇒ bbbbabbY ⇒ bbbbabbaY ⇒ bbbbabbaΛ = bbbbabba
S ⇒ YXY ⇒ ΛbbbaY ⇒ bbbabY ⇒ bbbabaY ⇒ bbbabaΛ = bbbaba
S ⇒ YXY ⇒ bYbbbaY ⇒ bΛbbbaΛ = bbbba
Example
Consider the following CFG S → SS|XaXaX|Λ X → bX|Λ It can be observed that, using prod.2, X generates Λ. X generates any number of b’s. Thus X generates the strings generated by b*. It may also be observed that the above CFG generates the language expressed by (b*ab*ab*)*.
Example
Consider the following CFG Σ = {a,b} productions: S → aSa|bSb|a|b|Λ The above CFG generates the language PALINDROME. It may be noted that the CFG S → aSa|bSb|a|b generates the language NON-NULLPALINDROME.
Example
Consider the following CFG Σ = {a,b} productions: S → aSb|ab|Λ It can be observed that the CFG generates the language {a^n b^n : n = 0,1,2,3, ...}. It may also be noted that the language {a^n b^n : n=1,2,3, ...} can be generated by the CFG, S → aSb|ab
Example
Consider the following CFG S → aXb|bXa X → aX|bX|Λ The above CFG generates the language of strings, defined over Σ={a,b}, beginning and ending in different letters.
Trees
As in English language any sentence can be expressed by parse tree, so any word generated by the given CFG can also be expressed by the parse tree, e.g. consider the following CFG S → AA A → AAA|bA|Ab|a Obviously, baab can be generated by the above CFG. To express the word baab as a parse tree, start with S. Replace S by the string AA, of nonterminals, drawing the downward lines from S to each character of this string as follows
S
|
A A
Now let the left A be replaced by bA and the right one by Ab then the tree will be
S
/ \
A A
| |
b A A b
Replacing both A’s by a, the above tree will be
S
/ \
A A
/ \ / \
b A A b
| |
a a
Thus the word baab is generated. The above tree to generate the word baab is called Syntax tree or Generation tree or Derivation tree as well.
🔑 Definition — Parse Tree (also Syntax tree, Generation tree, or Derivation tree): A tree structure used to represent the derivation of a string (a word) from a Context-Free Grammar. The root is the start symbol (S), internal nodes are non-terminals, and leaves are terminals (the symbols in the final string).
⭐ Key Takeaways
- Context-Free Grammars are a powerful tool for defining languages, and a single grammar can often be constructed for languages with specific constraints like EVEN-EVEN, EQUAL, PALINDROME, and {a^n b^n}.
- The production S → SS|Λ is a key construct that defines a language closed under concatenation, which is fundamental to generating languages expressed by r*.
- A non-terminal (like Y or X in examples) that generates (a+b)* or b* is often used as a "filler" to add any number of symbols on either side of a specific pattern (e.g., bbb).
- A parse tree (or derivation tree) provides a visual, hierarchical representation of the derivation of a word, showing how the start symbol is replaced by non-terminals and finally terminals.
- The same CFG can generate different languages; the inclusion or exclusion of a production like Λ critically changes the set of strings generated (e.g., {a^n b^n} with or without n=0).
🧠 Quick Revision Questions
- What is the role of a non-terminal in a context-free grammar?
- Write a CFG that generates the language {a^n b^n : n >= 0}.
- What is the primary difference between a derivation and a parse tree?
- How does the production S → SS influence the language generated by a grammar?
- Considering the CFG for PALINDROME (S → aSa|bSb|a|b|Λ), what modification is needed to generate only NON-NULLPALINDROME?
📘 Lecture 33 — Reading Material
📖 Overview: This lecture explores the concept of ambiguity in Context-Free Grammars (CFGs), demonstrating how ambiguous grammars can generate the same word through different derivation trees. It introduces Polish Notation (prefix notation) as an alternative representation for arithmetic expressions and shows how certain CFGs can be redesigned to eliminate ambiguity.
🗂️ Topics Covered
The lecture begins with an example of an ambiguous CFG for arithmetic expressions, showing two different derivation trees for the expression 3+4*5. It then demonstrates how ambiguity can be removed by modifying the grammar. Polish Notation (prefix notation) is introduced as an operator prefix notation for arithmetic expressions, with examples of evaluating prefix expressions. The lecture concludes with a formal definition of ambiguous CFGs and additional examples.
📝 Lecture Summary
Example
Consider the following CFG: S → S+S | SS | number where S and number are non-terminals and the operators behave like terminals. The above CFG creates ambiguity as the expression 3+45 has two possibilities: (3+4)5=35 and 3+(45)=23, which can be expressed by the following production trees:
Tree (i):
S
/|\
S + S
/| |\
3 S * S 5
| |
4 5
This evaluates to 3 + (4*5) = 3 + 20 = 23
Tree (ii):
S
/|\
S * S
/| |\
3 + 4 5
This evaluates to (3+4)5 = 75 = 35
The expressions can be calculated starting from bottom to the top, replacing each nonterminal by the result of calculation.
Example
S → (S+S) | (S*S) | number where S and number are nonterminals, while (, *, +, ) and the numbers are terminals.
Here it can be observed that: S ⇒ (S+S) ⇒ (S+(SS)) ⇒ (3+(45)) = 23 S ⇒ (S*S) ⇒ ((S+S)*S) ⇒ ((3+4)*5) = 35
Polish Notation (o-o-o)
There is another notation for arithmetic expressions for the CFG, S→S+S|S*S|number. Consider the following derivation trees:
Tree (i):
S
/|\
3 + S
/|\
4 * 5
Tree (ii):
S
/|\
S * 5
/|\
3 + 4
The arithmetic expressions shown by the trees (i) and (ii) can be calculated from the following trees, respectively:
Tree (i):
+
/ \
3 *
/ \
4 5
Tree (ii):
*
/ \
+ 5
/ \
3 4
Here most of the S's are eliminated. The branches are connected directly with the operators. Moreover, the operators + and * are no longer terminals as these are to be replaced by numbers (results).
To write the arithmetic expression, it is required to traverse from the left side of S and going onward around the tree. The arithmetic expressions will be as under:
(i) + 3 * 4 5 (ii) * + 3 4 5
The above notation is called operator prefix notation.
To evaluate the strings of characters, the first substring (from the left) of the form operator-operand-operand (o-o-o) is found and is replaced by its calculation e.g.
+3*4 5 = +3 20 = 23 *+3 4 5 = * 7 5 = 35
It may be noted that 4*5+3 is an infix arithmetic expression, while an arithmetic expression in (o-o-o) form is a prefix arithmetic expression.
🔑 Definition — Infix arithmetic expression: An expression where operators are placed between operands (e.g., 45+3). 🔑 Definition — Prefix arithmetic expression (Polish Notation): An expression where operators precede their operands (e.g., +345). 📌 Example: The prefix expression *+3 4 5 is evaluated by first finding the o-o-o substring "+3 4", evaluating it to 7, then evaluating "*7 5" to 35.
Example
To calculate the arithmetic expression of the following tree:
*
/ \
+ 6
/ \
* 5
/ \
+ +
/ \ / \
1 2 3 4
It can be written as: ++1 2+3 4 5 6
The above arithmetic expression in (o-o-o) form can be calculated as: ++1 2+3 4 5 6 = *+*3+3 4 5 6 = *+*3 7 5 6 = *+21 5 6 = *26 6 = 156
Note The previous prefix arithmetic expression can be converted into the following infix arithmetic expression as: ++1 2+3 4 5 6 = ++1 2 (3+4) 5 6 = +(1+2) (3+4) 5 6 = (((1+2)(3+4)) + 5) 6 = (((1+2)*(3+4)) + 5)*6
💡 Why this matters: Polish Notation eliminates the need for parentheses and precedence rules in evaluation, as the order of operations is unambiguous from the prefix structure.
Ambiguous CFG
🔑 Definition — Ambiguous CFG: The CFG is said to be ambiguous if there exists at least one word of its language that can be generated by different production trees.
Example: Consider the following CFG: S → aS | Sa | a
The word aaa can be generated by the following three different trees:
Tree 1:
S
/|\
a S
/|\
a S
|
a
Tree 2:
S
/|\
S a
/|\
S a
|
a
Tree 3:
S
/|\
S a
/|\
a S
|
a
Thus the above CFG is ambiguous, while the CFG, S→aS|a is not ambiguous as neither the word aaa nor any other word can be derived from more than one production trees. The derivation tree for aaa is as follows:
S
/|\
a S
/|\
a S
|
a
⭐ Key Takeaways
Ambiguous CFGs allow a single word to be generated by multiple distinct derivation trees, which can lead to multiple interpretations — as seen with the arithmetic expression 3+4*5 having two possible evaluations (23 vs 35). Polish Notation (prefix o-o-o notation) provides an unambiguous way to represent arithmetic expressions by placing operators before their operands, eliminating the need for parentheses. A CFG can be made unambiguous by restructuring its production rules, such as adding parentheses to force a specific evaluation order. The evaluation of a prefix expression involves repeatedly finding and replacing the leftmost operator-operand-operand substring with its calculated result until a single number remains. Not all CFGs are ambiguous; for example, S→aS|a is unambiguous because every word has exactly one derivation tree.
🧠 Quick Revision Questions
- What is an ambiguous CFG, and how does it relate to derivation trees?
- Why is the CFG S → S+S | SS | number considered ambiguous for the expression 3+45?
- How does Polish Notation (prefix notation) represent arithmetic expressions differently from infix notation?
- Describe the step-by-step evaluation of the prefix expression ++1 2+3 4 5 6.
- Give an example of an unambiguous CFG and explain why it is not ambiguous.
📘 Lecture 34 — Theory of Automata
📖 Overview: This lecture explores the concepts of ambiguous and unambiguous grammars, introduces the total language tree as a visualization tool, and establishes the connection between regular grammars and finite automata. It provides methods for converting between regular grammars and transition graphs, which is essential for understanding language generation and recognition.
🗂️ Topics Covered
The lecture covers examples of ambiguous and unambiguous grammars (including PALINDROME), the total language tree with finite and infinite tree examples, the definition and properties of regular grammar, the conversion from FA to CFG, the concepts of semiword and word, a theorem on regular grammar, and the method to build a TG for regular grammar.
📝 Lecture Summary
Example of Ambiguous Grammar
Consider the following CFG: S → aS | bS | aaS | . It can be observed that the word aaa can be derived from more than one production tree. Thus, the above CFG is ambiguous. This ambiguity can be removed by removing the production S → aaS.
Example of Unambiguous Grammar (PALINDROME)
Consider the CFG of the language PALINDROME: S → aSa | bSb | a | b | . It may be noted that this CFG is unambiguous as all the words of the language PALINDROME can only be generated by a unique production tree. It may be noted that if the production S → aaSaa is added to the given CFG, the CFG thus obtained will be no more unambiguous.
Total Language Tree
For a given CFG, a tree with the start symbol S as its root and whose nodes are working strings of terminals and non-terminals. The descendants of each node are all possible results of applying every production to the working string. This tree is called total language tree.
🔑 Definition — Total Language Tree: A tree with the start symbol S as its root, where nodes are working strings, and descendants are all possible results of applying every production to the working string.
📌 Example: Consider the following CFG: S → aa | bX | aXX, X → ab | b. The total language tree shows S branching to "aa", "bX", and "aXX". From "bX", we get "bab" and "bb". From "aXX", we get strings like "aabab", "aabb", "abab", and "abb". Dropping repeated words, the language generated is {aa, bab, bb, aabab, aabb, abab, abb}.
📌 Example: Consider the CFG: S → X | b, X → aX. The total language tree shows S branching to X and b. From X, we get aX, then aaX, then aaaX... This tree is infinite. Note: The only word in this language is b.
Regular Grammar
All regular languages can be generated by CFGs. Some nonregular languages can be generated by CFGs but not all possible languages can be generated by CFG, e.g., the CFG S → aSb | ab generates the language {aⁿbⁿ : n=1,2,3,...}, which is nonregular. It is to be noted that for every FA, there exists a CFG that generates the language accepted by this FA.
📌 Example: Consider the language L expressed by (a+b)aa(a+b), i.e., the language of strings, defined over Σ={a,b}, containing aa. To construct the CFG corresponding to L, consider the FA accepting L. The CFG corresponding to the FA may be: S → bS | aA, A → aB | bS, B → aB | bB | . It may be noted that the number of nonterminals in the above CFG is equal to the number of states of the corresponding FA, where the nonterminal S corresponds to the initial state and each transition defines a production.
💡 Why this matters: This establishes a direct connection between finite automata (language recognizers) and context-free grammars (language generators) for regular languages.
Semiword and Word
A semiword is a string of terminals (may be none) concatenated with exactly one nonterminal on the right, i.e., a semiword, in general, is of the following form: (terminal)(terminal)...(terminal)(nonterminal).
A word is a string of terminals. Λ (null string) is also a word.
🔑 Definition — Semiword: A string of terminals concatenated with exactly one nonterminal on the right. 🔑 Definition — Word: A string of terminals (including Λ).
Theorem
If every production in a CFG is one of the following forms:
- Nonterminal → semiword
- Nonterminal → word
then the language generated by that CFG is regular.
Regular Grammar Definition
A CFG is said to be a regular grammar if it generates a regular language, i.e., a CFG is said to be a regular grammar in which each production is one of the two forms:
- Nonterminal → semiword
- Nonterminal → word
📌 Example: The CFG S → aaS | bbS | is a regular grammar. It may be observed that this CFG generates the language of strings expressed by the RE (aa+bb)*. 📌 Example: The CFG S → aA | bB, A → aS | a, B → bS | b is a regular grammar. It may be observed that this CFG generates the language of strings expressed by RE (aa+bb)+.
Method to Build TG for Regular Grammar
For every regular grammar there exists a TG (Transition Graph) corresponding to the regular grammar. Following is the method to build a TG from the given regular grammar:
- Define the states of the required TG, equal in number to that of nonterminals of the given regular grammar.
- An additional state is also defined to be the final state.
- The initial state should correspond to the nonterminal S.
For every production of the given regular grammar, there are two possibilities for the transitions of the required TG:
- If the production is of the form nonterminal → semiword, then the transition of the required TG would start from the state corresponding to the nonterminal on the left side of the production and would end in the state corresponding to the nonterminal on the right side of the production, labeled by the string of terminals in the semiword.
- If the production is of the form nonterminal → word, then the transition of the TG would start from the state corresponding to the nonterminal on the left side of the production and would end on the final state of the TG, labeled by the word.
📌 Example: Consider the CFG S → aaS | bbS | . The TG accepting the language generated by this CFG has state S and an additional final state. From state S, there is a transition labeled "aa" back to S, a transition labeled "bb" back to S, and a transition labeled Λ from S to the final state. The corresponding RE may be (aa+bb)*.
⭐ Key Takeaways
In this lecture, you learned that ambiguity in a CFG occurs when a word has more than one derivation tree, and that the PALINDROME grammar is unambiguous in its standard form. The total language tree is a powerful tool for visualizing all possible derivations in a grammar, and it can be finite or infinite. You must remember that regular grammars are a restricted form of CFG where productions are limited to nonterminal→semiword or nonterminal→word forms, and that for every FA there exists a corresponding CFG. Finally, there is a systematic method to convert any regular grammar into a transition graph by creating states for each nonterminal plus a final state, and labeling transitions according to the production rules.
🧠 Quick Revision Questions
- What makes a context-free grammar ambiguous, and how can ambiguity be resolved in the given example S → aS | bS | aaS | ?
- Why is the CFG S → aSa | bSb | a | b | considered unambiguous for the PALINDROME language?
- What is a total language tree, and how do you determine the language generated by a CFG from its total language tree?
- What are the two production forms that define a regular grammar, and what theorem guarantees that the language generated is regular?
- Describe the step-by-step method to construct a Transition Graph from a given regular grammar.
📘 Lecture 35 — Theory of Automata
📖 Overview: This lecture covers the elimination of null productions, nullable productions, and unit productions from Context-Free Grammars (CFGs), and introduces Chomsky Normal Form (CNF). These transformations are essential for simplifying grammars while preserving language recognition, a critical step in parsing and compiler design.
🗂️ Topics Covered
The lecture begins with examples of building Transition Graphs (TGs) corresponding to Regular Grammars. It then defines and demonstrates the removal of null productions (of the form N → Λ), followed by nullable productions (nonterminals that can derive Λ indirectly). The process for eliminating unit productions (nonterminal → nonterminal) is shown with a detailed example. Finally, Chomsky Normal Form is defined as a grammar containing only productions of the form nonterminal → two nonterminals or nonterminal → one terminal.
📝 Lecture Summary
Examples of building TG's corresponding to the Regular Grammar
The lecture provides two examples of converting CFGs into TGs. In the first example, the CFG S → aA|bB, A → aS|a, B → bS|b corresponds to a TG with states S-, A, B, and a + state, producing the RE (aa+bb)+. The second example shows the CFG S → aaS|bbS|abX|baX|Λ, X → aaX|bbX|abS|baS generating a TG where the S- and X states loop with aa,bb and ab,ba respectively, and the language is EVEN-EVEN.
🔑 Definition — Regular Grammar to TG: A direct construction where each production nonterminal → string is represented as a transition between states in a Transition Graph.
Null Production
Null productions are productions of the form nonterminal → Λ. For example, in the CFG S → aA|bB|Λ, A → aa|Λ, B → aS, both S → Λ and A → Λ are null productions.
To eliminate null productions from a CFG while preserving the language (except for the word Λ itself), follow this method: Delete all null productions, and for each production containing the nullable nonterminal, add new productions where the nonterminal is omitted in all possible combinations. For example, given X → aNbNa and N → Λ, delete N → Λ and add X → aNba, X → abNa, and X → aba, keeping the original X → aNbNa.
Nullable Production
A nullable production is either a null production (N → Λ) or a production where there exists a derivation from the nonterminal N that eventually leads to Λ, i.e., N₁ → N₂, N₂ → N₃, ... Nₙ → Λ.
💡 Why this matters: Nullable productions can indirectly produce Λ through a chain of productions, and removing them requires handling all intermediate nonterminals.
The method for removing nullable productions is the same as for null productions, but applied to all nullable nonterminals. For the CFG: S → XaY|YY|aX|ZYX, X → Za|bZ|ZZ|Yb, Y → Ya|XY|Λ, Z → aX|YYY, the nullable productions are S → YY, X → ZZ, Z → YYY, and the null production is Y → Λ. The resulting CFG without null productions includes all combinations of omitting nullable nonterminals, e.g., S → XaY|Xa|aY|a|YY|Y|aX|ZYX|YX|ZX|ZY|X|Z.
📌 Example: Given S → XY, X → Zb, Y → bW, Z → AB, W → Z, A → aA|bA|Λ, B → Ba|Bb|Λ. Here A → Λ and B → Λ are null productions, while Z → AB and W → Z are nullable productions. The new CFG becomes: S → XY, X → Zb|b, Y → bW|b, Z → AB|A|B, W → Z, A → aA|a|bA|b, B → Ba|a|Bb|b.
Unit production
Unit productions are productions of the form nonterminal → one nonterminal. For example, in S → A|bb, A → B|b, B → S|a, the unit productions are S → A, A → B, and B → S.
To eliminate unit productions, separate them from nonunit productions. Then, for each unit production chain (e.g., S → A, A → B), add the right-hand sides of the nonunit productions reachable from the original nonterminal. The unit productions are then deleted.
📌 Example: From the unit productions S → A, A → B, B → S, and nonunit productions S → bb, A → b, B → a:
- S → A gives S → b (using A → b)
- S → A → B gives S → a (using B → a)
- A → B gives A → a (using B → a)
- A → B → S gives A → bb (using S → bb)
- B → S gives B → bb (using S → bb)
- B → S → A gives B → b (using A → b) The new CFG is S → a|b|bb, A → a|b|bb, B → a|b|bb, generating the finite language {a, b, bb}.
Chomsky Normal Form (Definition)
A CFG is in Chomsky Normal Form (CNF) if every production is of the form:
- nonterminal → string of two nonterminals, or
- nonterminal → one terminal
💡 Why this matters: CNF is a restricted form that simplifies parsing algorithms, such as the CYK algorithm, and is a standard step in many compiler and language processing applications.
⭐ Key Takeaways
The lecture presents three essential grammar transformations: null/ nullable production removal and unit production elimination, with detailed examples for each. Null and nullable productions are removed by replacing nullable nonterminals with all possible combinations of their presence or absence, while unit productions are eliminated by substituting the chain of nonterminals with their terminal or nonunit derivations. Chomsky Normal Form is defined as a grammar restricted to productions of two nonterminals or one terminal, forming a foundational structure for efficient parsing algorithms.
🧠 Quick Revision Questions
- What is the difference between a null production and a nullable production?
- In the CFG S → XaY, X → Za, Y → Λ, Z → aX, which productions are nullable and which are null?
- How would you eliminate the unit production S → A from a CFG where A → bB|a and B → c?
- Why must the word Λ be treated separately when removing null productions from a CFG?
- What two forms must all productions take for a CFG to be in Chomsky Normal Form?
📘 Lecture 36 — Chomsky Normal Form
📖 Overview: This lecture introduces the Chomsky Normal Form (CNF) and proves that any context-free grammar can be converted into CNF to generate all nonnull words of the corresponding CFL. It also covers the construction of FAs from regular CFGs, leftmost and rightmost derivations, and sets the stage for a new, more powerful class of machines accepting CFLs.
🗂️ Topics Covered
The lecture covers the definition of Chomsky Normal Form (CNF) and the theorem that all nonnull words of a CFL can be generated by a CFG in CNF. It provides detailed examples of converting CFGs to CNF, including handling null and unit productions. It also presents an example of an FA corresponding to a regular CFG, defines leftmost and rightmost derivations with examples and a theorem, and introduces the concept of a new format for FAs to accept CFLs.
📝 Lecture Summary
Chomsky Normal Form (CNF)
If a CFG has only productions of the form nonterminal → string of two nonterminals or nonterminal → one terminal, then the CFG is said to be in Chomsky Normal Form (CNF).
💡 Why this matters: CNF is a standardized form that simplifies the analysis of CFGs, especially for proving properties about CFLs.
Note: Any CFG can be converted to be in CNF, if the null productions and unit productions are removed. Also, if a CFG contains nullable productions, then the corresponding new productions are also to be added.
Theorem
All NONNULL words of the CFL can be generated by the corresponding CFG which is in CNF, i.e., the grammar in CNF will generate the same language except the null string.
Example (PALINDROME)
Consider the following CFG: S → aSa | bSb | a | b | aa | bb
To convert to CNF, introduce new productions A → a, B → b, then the new CFG will be: S → ASA | BSB | AA | BB | a | b A → a B → b
Introduce nonterminals R₁ and R₂ so that: S → AR₁ | BR₂ | AA | BB | a | b R₁ → SA R₂ → SB A → a B → b
which is in CNF.
🔑 Definition — Chomsky Normal Form (CNF): A CFG is in CNF if all productions are of the form nonterminal → two nonterminals or nonterminal → one terminal.
📐 Procedure: Convert CFG to CNF by:
- Remove null productions
- Remove unit productions
- Introduce new nonterminals for terminals
- Break productions with more than two nonterminals into binary form
📌 Example: The CFG S → aSa | bSb | a | b | aa | bb generates NONNULLPALINDROME. After conversion to CNF, it uses S → AR₁ | BR₂ | AA | BB | a | b, R₁ → SA, R₂ → SB, A → a, B → b.
Example (with null productions)
Consider the following CFG: S → ABAB A → a | Ѓ B → b | Ѓ
Here, S → ABAB is a nullable production and A → Ѓ, B → Ѓ are null productions.
Step 1: Removing null productions A → Ѓ and B → Ѓ, and introducing new productions: S → BAB | AAB | ABB | ABA | AA | AB | BA | BB | A | B
Step 2: Now S → A and S → B are unit productions to be eliminated:
- S → A gives S → a (using A → a)
- S → B gives S → b (using B → b)
The new resultant CFG takes the form: S → BAB | AAB | ABB | ABA | AA | AB | BA | BB | a | b A → a B → b
Step 3: Introduce the nonterminal C where C → AB, so that: S → BC | AC | CB | CA | AA | C | BA | BB | a | b A → a B → b C → AB is the CFG in CNF.
Example of an FA corresponding to Regular CFG
To construct an FA that accepts the grammar: S → abA A → baB B → aA | bb
The language can be identified by the three words generated:
Derivation 1: S ⇒ abA ⇒ abbaB (using A→baB) ⇒ abbabb (using B→bb)
Derivation 2: S ⇒ abA ⇒ abbaB (using A→baB) ⇒ abbaaA (using B→aA) ⇒ abbaabaB (using A→baB) ⇒ abbaababb (using B→bb)
Derivation 3: S ⇒ abA ⇒ abbaB (using A→baB) ⇒ abbaaA (using B→aA) ⇒ abbaabaB (using A→baB) ⇒ abbaabaaA (using B→aA) ⇒ abbaabaabaB (using A→baB) ⇒ abbaabaababb (using B→bb)
This shows that the corresponding language has RE: *abba(aba)bb
The FA accepting the given CFG may be: [S-] --a--> [A] --b--> [B] --a--> [A] --b--> [+] [B] --b--> [+] [B] --a--> [A]
Leftmost Derivation
Definition: The derivation of a word w, generated by a CFG, such that at each step, a production is applied to the leftmost nonterminal in the working string, is said to be leftmost derivation.
🔑 Definition — Leftmost nonterminal: The nonterminal that occurs first from the left in the working string.
Example
Consider the following CFG: S → XY X → XX | a Y → YY | b
Following are two leftmost derivations of aaabb:
Derivation 1: S ⇒ XY ⇒ XXY ⇒ aXY ⇒ aXXY ⇒ aaXY ⇒ aaaY ⇒ aaaYY ⇒ aaabY ⇒ aaabb
Derivation 2: S ⇒ XY ⇒ XXY ⇒ XXXY ⇒ aXXY ⇒ aaXY ⇒ aaaY ⇒ aaaYY ⇒ aaabY ⇒ aaabb
Theorem
Any word that can be generated by a certain CFG has also a leftmost derivation.
Note: The above theorem can be stated for rightmost derivation as well.
Example (Leftmost vs Rightmost)
Consider the following CFG: S → YX X → XX | b Y → YY | a
Following are the leftmost and rightmost derivations of abbbb:
Leftmost derivation: S ⇒ YX ⇒ aX ⇒ aXX ⇒ abX ⇒ abXX ⇒ abbX ⇒ abbXX ⇒ abbbX ⇒ abbbb
Rightmost derivation: S ⇒ YX ⇒ YXX ⇒ YXb ⇒ YXXb ⇒ YXbb ⇒ YXXbb ⇒ YXbbb ⇒ Ybbbb ⇒ abbbb
A New Format for FAs
A class of machines (FAs) has been discussed accepting the regular language. It has also been discussed that there is a CFG corresponding to regular language, and CFGs also define some nonregular languages.
There is a question: is there a class of machines accepting the CFLs? The answer is yes. The new machines which are to be defined are more powerful and can be constructed with the help of FAs with a new format.
💡 Why this matters: This sets the foundation for Pushdown Automata (PDA) which accept CFLs.
⭐ Key Takeaways
A student must remember that Chomsky Normal Form (CNF) requires all productions to be either nonterminal → two nonterminals or nonterminal → one terminal, and any CFG can be converted to CNF by removing null and unit productions. The leftmost derivation applies a production to the leftmost nonterminal at each step, and the theorem states that any word generated by a CFG has a leftmost derivation. The example of an FA from a regular CFG shows the correspondence between regular grammars and finite automata. Finally, the new format for FAs introduces the idea that more powerful machines are needed to accept CFLs, leading to the concept of Pushdown Automata (PDA) .
🧠 Quick Revision Questions
- What are the two allowed production forms in Chomsky Normal Form (CNF)?
- According to the theorem, what type of words does a CFG in CNF generate?
- In the example converting
S → aSa|bSb|a|b|aa|bbto CNF, what is the role of the new nonterminalsR₁andR₂? - What is the definition of a leftmost derivation?
- Based on the example with grammar
S → abA, A → baB, B → aA|bb, what is the regular expression for the language generated?
📘 Lecture 37 — New Format for FAs, PDA
📖 Overview: This lecture introduces a new format for Finite Automata (FAs) and extends it to create Pushdown Automata (PDAs), which are machines capable of accepting Context-Free Languages (CFLs). It explains the components of this new format, including the input TAPE, START, ACCEPT, REJECT, and READ states, and then introduces the PUSHDOWN STACK with PUSH and POP operations. The lecture culminates with an example of a PDA that recognizes the non-regular language {aⁿbⁿ : n ≥ 0}, demonstrating the increased power of this new machine class.
🗂️ Topics Covered
The lecture begins by questioning whether there is a class of machines accepting CFLs, answering with the introduction of Pushdown Automata (PDAs) built from FAs in a new format. It defines the components of this new FA format: the Input TAPE (partitioned into cells for input letters), START state, ACCEPT state, REJECT state, and READ state. Two examples illustrate the new format for FAs accepting (a+b)*a and (a+b)bb(a+b). Then, the PUSHDOWN STACK is introduced as a memory structure, along with PUSH and POP operations. An example PDA accepting the language {aⁿbⁿ : n ≥ 0} is presented with a step-by-step walkthrough of processing the string aaabbb.
📝 Lecture Summary
New format for FAs
A new class of machines, more powerful than simple FAs, is needed to accept Context-Free Languages (CFLs). These machines are built by first defining a new format for FAs. The components of this new format are:
- Input TAPE: The part of an FA where the input string is placed before it is run. The input TAPE is partitioned into cells, so each letter of the input string can be placed in each cell. The input string abbaa is shown in the following input TAPE: Cell i (a), Cell ii (b), Cell iii (b), Cell iv (a), Cell v (a), then ∆ (blank). The character ∆ indicates a blank in the TAPE. It is assumed that when the first ∆ is read, the rest of the TAPE is supposed to be blank.
- The START state: This state is like the initial state of an FA and is represented by a small circle.
- An ACCEPT state: This state is like a final state of an FA and is expressed by a circle with a dot inside.
- A REJECT state: This state is like a dead-end non-final state and is expressed by an open circle.
- 💡 Why this matters: The ACCEPT and REJECT states are called the halt states.
- A READ state: This state is to read an input letter and lead to some other state. The READ state is expressed by a rectangle with a downward arrow on the left side.
Example
Consider an FA along with its new format. The FA accepts the language of strings expressed by (a+b)*a. The new format of this FA is: a START state leads to a READ state (with a self-loop for b). The READ state has an edge labeled 'a' to a second READ state (with a self-loop for b). The first READ state also has an edge labeled ∆ (blank) to a REJECT state. The second READ state has an edge labeled ∆ to an ACCEPT state. The ∆ edge should not be confused with a Λ-labeled edge. ∆-edges start only from READ boxes and lead to halt states.
Example
Another example shows an FA that accepts the language expressed by (a+b)bb(a+b). This FA, in its new format, would have START, READ states, and edges labeled with a, b, and ∆ leading to ACCEPT or REJECT states.
PUSHDOWN STACK or PUSHDOWN STORE
PUSHDOWN STACK is a place where the input letters can be placed until these letters are referred again. It can store as many letters as one can in a long column. Initially the STACK is supposed to be empty, i.e., each of its storage locations contains a blank (∆).
- PUSH: A PUSH operator adds a new letter at the top of STACK. For example, if the letters a, b, c, and d are pushed to the STACK that was initially blank, the STACK can be shown as d (top), c, b, a, ∆ (bottom). The PUSH state is expressed by a rectangle with "PUSH" and the letter being pushed. When a letter is pushed, it replaces the existing letter and pushes it one position below.
- POP and STACK: POP is an operation that takes out a letter from the top of the STACK. The rest of the letters are moved one location up. The POP state is expressed by a rectangle with "POP" and a letter (or variable). Note that popping an empty STACK is like reading an empty TAPE, i.e., popping a blank character ∆.
- 💡 Why this matters: When the new format of an FA contains PUSH and POP states, it is called PUSHDOWN Automata or PDAs. Adding the PUSHDOWN STACK (the memory structure) to an FA increases its language-recognizing capabilities considerably.
Example
Consider the following PDA that accepts the language {aⁿbⁿ : n = 0, 1, 2, ...}. The PDA has states: START, READ₁, PUSH a, POP₁, READ₂, POP₂, ACCEPT, and REJECT. The transitions are:
- START → READ₁
- READ₁: reading 'a' → PUSH a; reading ∆ → POP₂
- PUSH a → READ₁
- READ₁: reading 'b' → POP₁
- POP₁: popping 'a' → READ₂; popping ∆ → REJECT
- READ₂: reading 'b' → POP₁; reading ∆ → POP₂
- POP₂: popping ∆ → ACCEPT; popping 'a' → REJECT
The string aaabbb is run on this machine.
- The string is placed on the TAPE (a a a b b b ∆ ∆ ...) and the STACK is empty (∆ at top).
- Reading the first 'a' from the TAPE, we move from READ₁ to PUSH a state. This causes the letter 'a' to be deleted from the TAPE and added to the top of the STACK.
- Reading the next two 'a's successively will delete further two 'a's from the TAPE and add these letters to the top of the STACK. The STACK now has: a (top), a, a, ∆, ∆, ...
- Reading the next letter, which is 'b', from the TAPE will lead to the POP₁ state. The top letter at the STACK is 'a', which is popped out, and READ₂ state is entered. The STACK now has: a (top), a, ∆, ...
- Reading the next two 'b's successively will delete two 'b's from the TAPE, will lead to the POP₁ state, and these 'b's will remove the 'a's from the STACK one by one. The STACK now has: ∆ (top), ∆, ...
- Now there is only the blank character ∆ left to be read from the TAPE, which leads to POP₂ state. While only blank characters are left in the STACK to be popped out, the ACCEPT state is entered, showing that the string aaabbb is accepted by this PDA. It may be observed that the above PDA accepts the language {aⁿbⁿ: n = 0, 1, 2, ...}. Since the null string is like a blank character, reading ∆ at state READ₁ leads to POP₂ state, and POP₂ state contains only ∆, hence it leads to ACCEPT state, and the null string is accepted.
🔑 Definition — PDA (Pushdown Automaton): An FA equipped with a PUSHDOWN STACK and PUSH/POP operations, capable of accepting Context-Free Languages.
📐 Formula: L = {aⁿbⁿ : n ≥ 0} → A non-regular language that is a CFL, accepted by a PDA by pushing 'a's and popping them with corresponding 'b's.
📌 Example: Running the string aaabbb on the PDA.
- Initial State: TAPE = [a, a, a, b, b, b, ∆, ∆,...], STACK = [∆, ∆, ∆,...] (empty)
- Step 1: Read 'a' from TAPE → PUSH 'a' → STACK = [a, ∆, ∆,...]
- Step 2: Read 'a' from TAPE → PUSH 'a' → STACK = [a, a, ∆,...]
- Step 3: Read 'a' from TAPE → PUSH 'a' → STACK = [a, a, a, ∆,...]
- Step 4: Read 'b' from TAPE → POP 'a' from STACK → STACK = [a, a, ∆,...]
- Step 5: Read 'b' from TAPE → POP 'a' from STACK → STACK = [a, ∆, ∆,...]
- Step 6: Read 'b' from TAPE → POP 'a' from STACK → STACK = [∆, ∆, ∆,...]
- Step 7: Read ∆ from TAPE → POP ∆ from STACK → ACCEPT.
⭐ Key Takeaways
The most critical point is that adding a stack memory structure transforms an FA into a Pushdown Automaton (PDA), which is a fundamentally more powerful machine capable of accepting Context-Free Languages. You must understand the new format for FAs, including the Input TAPE and the START, ACCEPT, REJECT, and READ states, as this is the foundation for the PDA. The PUSHDOWN STACK, with its PUSH and POP operations, provides the mechanism to count and match symbols, which is essential for recognizing languages like {aⁿbⁿ}. The example of the PDA accepting {aⁿbⁿ} is a classic and must be understood process-wise, as it demonstrates the core concept of pushing and popping. Finally, remember that ∆ represents a blank on both the TAPE and the STACK, and that reading or popping a blank leads to halt states.
🧠 Quick Revision Questions
- What is the new component that is added to an FA to create a PDA, and what two operations does it support?
- In the new format for an FA, what is the difference between an ACCEPT state and a REJECT state, and what are they collectively called?
- Using the PDA from the lecture, explain step-by-step how the string "aabb" would be processed to reach an ACCEPT state.
- What would happen if the string "aab" were run on the PDA designed for {aⁿbⁿ}? Draw the final state.
- Why is a PDA considered more powerful than a standard FA? Give an example of a language that a PDA can recognize but an FA cannot.
📘 Lecture 38 — Theory of Automata
📖 Overview: This lecture covers Pushdown Automata (PDA) in detail, including deterministic and nondeterministic varieties. It provides worked examples of running strings through PDAs, introduces the formal definition of PDA, and demonstrates how PDAs correspond to context-free languages (CFLs).
🗂️ Topics Covered
The lecture begins with a table-based trace of running the string aaabbb through a PDA that accepts the language {aⁿbⁿ : n = 0,1,2,3,...}. It then presents an equivalent PDA representation, followed by an example of a PDA corresponding to the EVEN-EVEN language FA. Nondeterministic PDA is introduced with the EVENPALINDROME example, followed by the complete formal definition of Pushdown Automaton. Finally, an example PDA is given for the CFG S → S+S | S*S | 4, with a full trace of the string 4+4*4.
📝 Lecture Summary
Example of PDA with table for running a string
The process of running the string aaabbb through a PDA that accepts {aⁿbⁿ} is expressed in a state-stack-tape table.
The sequence is:
- START, then READ₁ (with ∆ on stack,
aaabbb∆...on tape) - PUSH a → stack becomes
a∆ - READ₁ again, PUSH a → stack becomes
aa∆ - READ₁ again, PUSH a → stack becomes
aaa∆ - READ₁ → POP₁ → stack becomes
aa∆ - READ₂ → POP₁ → stack becomes
a∆ - READ₂ → POP₁ → stack becomes
∆ - READ₂ → POP₂ → stack remains
∆ - ACCEPT
🔑 Definition — Language accepted: The above PDA accepts the language {aⁿbⁿ : n = 0,1,2,3,...} — strings with equal numbers of a's followed by b's.
📐 Observation: The TAPE alphabet Σ and STACK alphabet Γ may be different in general.
Equivalent PDA
The PDA equivalent to the one accepting {aⁿbⁿ} is presented with a diagram showing:
- START → READ₁ (loop: PUSH a on
a, stay at READ₁) - READ₁ → POP₁ (on
b) - POP₁ → loop on
a(PUSH a) andb(POP₁), or go to READ₂ on∆ - READ₂ → loop on POP₁ and POP₂, leading to ACCEPT on
∆
PDA for EVEN-EVEN Language
An FA for the EVEN-EVEN language is given (languages with an even number of a's and even number of b's).
The corresponding PDA is constructed from this FA, with states:
- START → READ states with transitions for
aandb - Leading to ACCEPT
Each transition in the FA corresponds to a READ state in the PDA.
Nondeterministic PDA
Like TGs and NFAs, if a PDA has more than one outgoing edge at READ or POP states with the same label, this creates nondeterminism. Such a PDA is called a nondeterministic PDA.
🔑 Key properties:
- No edge is labeled by a string of terminals or nonterminals
- If there is no edge for a letter to be read, the machine crashes and the string is rejected
- A string may trace more than one path
- If at least one path leads to ACCEPT, the string is accepted; otherwise rejected
📌 Example: Nondeterminism occurs at state READ₁ in the PDA for EVENPALINDROME.
📌 Example — EVENPALINDROME: The nondeterministic PDA accepts the language
EVENPALINDROME = {w reverse(w) : w ∈ {a,b}*}
= {Λ, aa, bb, aaaa, abba, baab, bbbb, ...}
Definition of PUSHDOWN AUTOMATON (PDA) — including nondeterminism
Pushdown Automaton (PDA) consists of:
- An alphabet Σ of input letters
- An input TAPE with infinitely many locations in one direction. Initially the input string is placed starting from the first cell; the remaining part is empty
- An alphabet Γ of STACK characters
- A pushdown STACK which is initially empty, with infinitely many locations in one direction. Initially the STACK contains blanks
- One START state with only one out-edge and no in-edge
- Two halt states: ACCEPT and REJECT states, with in-edges and no out-edges
- A PUSH state that introduces characters onto the top of the STACK
- A POP state that reads the top character of the STACK (may contain more than one out-edges with the same label)
- A READ state that reads the next unused letter from the TAPE (may contain more than one out-edges with the same label)
Example of Non-Deterministic PDA — CFG S → S+S | S*S | 4
Consider the CFG:
S → S+S | S*S | 4
The PDA accepting the corresponding CFL has the following structure:
- START → PUSH₁ S
- POP → loops back to:
- PUSH₂ S (followed by PUSH₃ +, then PUSH₄ S) → back to POP
- PUSH₅ S (followed by PUSH₆ *, then PUSH₇ S) → back to POP
- READ₁ (on ∆)
- READ₁ → loop to POP (on any letter), or go to READ₂, READ₃, READ₄
- Final transitions lead to ACCEPT
📌 Example — String 4+4*4 trace:
| STATE | STACK | TAPE |
|---|---|---|
| START | ∆ | 4+4*4 |
| PUSH₁ S | S | 4+4*4 |
| POP | ∆ | 4+4*4 |
| PUSH₂ S | S | 4+4*4 |
| PUSH₃ + | +S | 4+4*4 |
| PUSH₄ S | S+S | 4+4*4 |
| POP | +S | 4+4*4 |
| READ₁ | +S | +4*4 |
| POP | S | +4*4 |
| READ₂ | S | 4*4 |
| POP | ∆ | 4*4 |
| PUSH₅ S | S | 4*4 |
| PUSH₆ * | *S | 4*4 |
| PUSH₇ S | S*S | 4*4 |
| POP | *S | 4*4 |
| READ₁ | *S | *4 |
| POP | S | *4 |
| READ₃ | S | 4 |
| POP | ∆ | 4 |
| READ₁ | ∆ | ∆ |
| POP | ∆ | ∆ |
| READ₄ | ∆ | ∆ |
| ACCEPT | ∆ | ∆ |
💡 Why this matters: The choice of path at POP state can be determined by the leftmost derivation of the string belonging to the CFL. Letters are deleted from the TAPE instead of underlined.
⭐ Key Takeaways
- A PDA for {aⁿbⁿ} uses the stack to count a's (push) and match b's (pop), accepting when stack is empty at end of input.
- Nondeterministic PDAs have multiple outgoing edges from READ or POP states with the same label; a string is accepted if any path leads to ACCEPT.
- The formal PDA definition includes an input TAPE alphabet Σ, a STACK alphabet Γ, START, ACCEPT, REJECT, PUSH, POP, and READ states.
- PDAs can be constructed from CFGs where each production corresponds to a PUSH sequence, and the POP-READ loop simulates leftmost derivation.
- The EVENPALINDROME language demonstrates nondeterminism — the PDA must guess when the middle of the palindrome is reached.
🧠 Quick Revision Questions
- How does a deterministic PDA accept the language {aⁿbⁿ : n ≥ 0}? Describe the stack operations.
- What creates nondeterminism in a PDA, and how is acceptance determined in a nondeterministic PDA?
- List all nine components of the formal definition of a Pushdown Automaton.
- For the CFG S → S+S | S*S | 4, what is the leftmost derivation of the string
4+4*4? - How does the PDA for EVENPALINDROME differ from the PDA for {aⁿbⁿ}?
📘 Lecture 39 — PDA corresponding to CFG, Examples of PDA corresponding to CFG
📖 Overview: This lecture proves the theorem that for any Context-Free Grammar (CFG), there exists a Pushdown Automaton (PDA) that accepts the language generated by that CFG. It demonstrates the construction algorithm using examples of CFGs in Chomsky Normal Form (CNF) and shows step-by-step how the PDA processes input words through leftmost derivations.
🗂️ Topics Covered
The lecture covers the theorem stating that corresponding to any CFG there exists a PDA accepting the language generated by the CFG. It explains how to construct the PDA when the CFG is in CNF, shows a detailed example with the word "aab" including the complete state-transition table, and provides a second example converting a CFG with terminals into CNF before constructing its corresponding PDA.
📝 Lecture Summary
PDA corresponding to CFG
Theorem: Corresponding to any CFG there exists a PDA accepting the language generated by the CFG.
Since an algorithm has already been discussed to convert the CFG in CNF (Chomsky Normal Form), so the PDA can be constructed corresponding to the CFG. As the CFG in CNF generates all the nonnull words of the corresponding CFL (Context-Free Language), accepting the null string (if it is contained in the CFL) can be managed separately.
💡 Why this matters: This theorem establishes the equivalence between CFGs and PDAs, showing that these two different models of computation describe exactly the same class of languages.
Example 1
Consider the following CFG which is in CNF and does not generate the null string:
S → SB | AB A → CC B → b C → a
The corresponding PDA will have:
- STACK alphabet Γ = {S, A, B, C}
- TAPE alphabet Σ = {a, b}
The PDA structure includes:
- START state
- PUSH S state
- POP state
- PUSH A, PUSH B, PUSH C states
- READ₁, READ₂, READ₃ states
- ACCEPT state
Note: It may be noted that when the POP state is entered either a nonterminal is replaced by two nonterminals at the top of the STACK accommodating a production, or a nonterminal is popped out from the top of the stack and a READ state is entered to read a specified letter from the TAPE or else the machine crashes.
The choice of path taken at POP state to accommodate the word belonging to the CFL can be determined by the leftmost derivation of the word.
Consider the word aab with its leftmost derivation:
| Working-String Generation | Production Used |
|---|---|
| S ⇒ AB | S → AB (step 1) |
| ⇒ CCB | A → CC (step 2) |
| ⇒ aCB | C → a (step 3) |
| ⇒ aaB | C → a (step 4) |
| ⇒ aab | B → b (step 5) |
Step-by-step execution of the PDA for "aab":
-
START state is entered → STACK: ∆, TAPE: aab∆
-
PUSH S state is entered → STACK: S, TAPE: aab∆
-
POP state is entered → to accommodate production S → AB, PUSH B and PUSH A states are entered → STACK: AB, TAPE: aab∆
-
POP state is entered → to accommodate production A → CC, PUSH C, PUSH C states are entered → STACK: CCB, TAPE: aab
-
POP state is entered → to accommodate production C → a, READ₁ is entered and the letter a is read from the TAPE → STACK: CB, TAPE: aab
-
POP state is entered → to accommodate production C → a, READ₁ state is entered and the letter a is read from the TAPE → STACK: B, TAPE: aab
-
POP state is entered → to accommodate production B → b, READ₂ state is entered and the letter b is read from the TAPE → STACK: ∆, TAPE: aab
-
The ∆ shown in the STACK indicates that there are no nonterminals in the working string and ∆ is read from the STACK which leads to READ₃ state where the ∆ is read from the TAPE and the ACCEPT state is entered which shows that the word aab is accepted by the PDA.
Complete table for word "aab":
| Leftmost Derivation | STATE | STACK | TAPE |
|---|---|---|---|
| START | ∆ | aab | |
| S | PUSH S | S | aab |
| POP | ∆ | aab | |
| PUSH B | B | aab | |
| ⇒AB | PUSH A | AB | aab |
| POP | B | aab | |
| PUSH C | CB | aab | |
| ⇒CCB | PUSH C | CCB | aab |
| POP | CB | aab | |
| ⇒aCB | READ₁ | CB | aab |
| POP | B | aab | |
| ⇒aaB | READ₁ | B | aab |
| POP | ∆ | aab | |
| ⇒aab | READ₂ | ∆ | aab |
| POP | ∆ | aab | |
| READ₃ | ∆ | aab | |
| ACCEPT | ∆ | aab |
Example 2
Consider the following CFG:
S → XY X → aX | bX | a Y → Ya | Yb | a
First of all, converting the CFG to be in CNF, introduce the nonterminals A and B as:
A → a B → b
The following CFG is in CNF:
S → XY X → AX | BX | a Y → YA | YB | a A → a B → b
The PDA corresponding to this CFG includes:
- START state
- PUSH S state
- POP state
- PUSH X, PUSH A, PUSH B, PUSH Y states
- READ₁, READ₂, READ₃, READ₄, READ₅ states
- ACCEPT state
The word aaab can be generated as:
| Working-String Generation | Production Used |
|---|---|
| S ⇒ XY | S → XY (step 1) |
| ⇒ AXY | X → AX (step 2) |
| ⇒ aXY | A → a (step 3) |
| ⇒ aaY | X → a (step 4) |
| ⇒ aaYB | Y → YB (step 5) |
| ⇒ aaaB | Y → a (step 6) |
| ⇒ aaab | B → b (step 7) |
Step-by-step execution table for "aaab":
| STATE | STACK | TAPE |
|---|---|---|
| START | ∆ | aaab |
| PUSH S | S | aaab |
| POP | ∆ | aaab |
| PUSH Y | Y | aaab |
| PUSH X | XY | aaab |
| POP | Y | aaab |
| PUSH X | XY | aaab |
| PUSH A | AXY | aaab |
| POP | XY | aaab |
| READ₃ | XY | aaab |
| POP | Y | aaab |
| READ₁ | Y | aaab |
| POP | ∆ | aabb |
| PUSH B | B | aabb |
| PUSH Y | YB | aabb |
| POP | B | aaab |
| READ₂ | B | aaab |
| POP | ∆ | aaab |
| READ₄ | ∆ | aaab |
| POP | ∆ | ∆ |
| READ₅ | ||
| ACCEPT |
⭐ Key Takeaways
The critical concept is that any CFG can be converted into a PDA that accepts exactly the language generated by that grammar. The construction algorithm requires the CFG to be in Chomsky Normal Form first, then builds a PDA that simulates leftmost derivations by pushing and popping nonterminals on the stack while reading input letters. The PDA uses its stack to hold the working string during derivation, and each production is applied by pushing the right-hand side symbols (in reverse order) onto the stack when a nonterminal is popped. The acceptance condition occurs when both the stack and the input tape contain only the end-marker ∆, confirming that the entire word has been derived.
🧠 Quick Revision Questions
-
What is the STACK alphabet and TAPE alphabet in the first example's PDA corresponding to the CFG S → SB|AB, A → CC, B → b, C → a?
-
How does the PDA determine which path to take at the POP state when accommodating a word belonging to the CFL?
-
In the execution of the PDA for word "aab", which production is applied when the STACK contains "CCB" and the POP state is entered?
-
Why must the CFG be converted to Chomsky Normal Form before constructing the corresponding PDA?
-
In the second example, what two nonterminals are introduced to convert the original CFG into CNF, and what terminals do they represent?
📘 Lecture 40 — Recap of example of PDA corresponding to CFG, CFG corresponding to PDA. Theorem, HERE state, Definition of Conversion form, different situations of PDA to be converted into conversion form
📖 Overview: This lecture revisits the relationship between Context-Free Grammars (CFGs) and Pushdown Automata (PDAs), demonstrating how to convert a CFG into a corresponding PDA. It then introduces a theorem stating that for every PDA, there exists an equivalent CFG, and presents the necessary steps to convert a PDA into a standard "conversion form" by defining the HERE state and modifying the PDA structure to meet six specific conditions.
🗂️ Topics Covered
The lecture covers an example of converting a CFG to CNF and then to a PDA; the theorem that a CFG can be generated from any PDA; the definition and purpose of the HERE state; the six conditions for a PDA to be in conversion form; and a detailed explanation of the different situations that arise when modifying a PDA to satisfy each condition.
📝 Lecture Summary
Example
Consider the following CFG: S → XY, X → aX | bX | a, Y → Ya | Yb | a. First, convert the CFG to be in CNF (Chomsky Normal Form). Introduce the nonterminals A and B as A → a and B → b. The resulting CFG in CNF is: S → XY, X → AX | BX | a, Y → YA | YB | a, A → a, B → b. The PDA corresponding to this CFG will have states including PUSH X, PUSH A, PUSH B, and PUSH Y, directly mirroring the productions.
Theorem
Theorem: Given a PDA that accepts the language L, there exists a CFG that generates exactly L. Before the CFG corresponding to the given PDA is determined, the PDA is converted into a standard form called the conversion form. Before the PDA is converted into conversion form, a new state called HERE is defined, which is placed in the middle of any edge. Like READ and POP states, HERE states are also numbered (e.g., HERE₇).
Conversion form of PDA
Definition: A PDA is in conversion form if it fulfills the following conditions:
- There is only one ACCEPT state.
- There are no REJECT states.
- Every READ or HERE is followed immediately by a POP (i.e., every edge leading out of any READ or HERE state goes directly into a POP state).
- No two POPs exist in a row on the same path without a READ or HERE between them (whether or not there are any intervening PUSH states — the POP states must be separated by READs or HEREs).
- All branching, deterministic or nondeterministic, occurs at READ or HERE states, none at POP states, and every edge has only one label.
- Even before we get to START, a bottom-of-STACK symbol $ is placed on the STACK. If this symbol is ever popped in processing, it must be replaced immediately. The STACK is never popped beneath this symbol. Right before entering ACCEPT, this symbol is popped out and left. The PDA must begin with the sequence PUSH $. The entire input string must be read before the machine can accept the word.
🔑 Definition — Conversion Form: A standardized PDA structure that satisfies six specific conditions (single ACCEPT, no REJECT, READ/HERE followed by POP, no consecutive POPs, branching only at READ/HERE, and a $ bottom-of-stack symbol), which is necessary to construct an equivalent CFG.
Different situations of a PDA to be converted into conversion form are discussed as follows
To satisfy condition 3: Every READ or HERE must be followed immediately by a POP. An edge from READ₃ reading "b" that goes directly to another state must be modified by inserting a POP state between them. 📌 Example: A transition from READ₃ reading "b" becomes READ₃ → POP → (next state).
To satisfy condition 4: No two POPs can appear in a row. If a path has two consecutive POP states, a HERE state must be inserted between them. 📌 Example: POP → POP becomes POP → HERE → POP.
To satisfy condition 5: Branching must occur only at READ or HERE states, not at POP states. A POP state that has multiple outgoing edges must be restructured. 📌 Example: A POP with two outgoing edges becomes POP → READ₃ → (two branches).
To satisfy condition 5 (another case): A POP state that both reads and branches must be separated. 📌 Example: A POP that directly goes to two different states becomes POP → HERE → (two branches).
To satisfy condition 6: The STACK is initially configured with the $ symbol at the bottom. The machine must start with PUSH $, and the $ symbol is popped only right before ACCEPT. 💡 Why this matters: These modifications ensure the PDA is in a predictable, standardized form, which is essential for the theorem that a CFG can be systematically derived from it.
⭐ Key Takeaways
The most critical concept is that CFGs and PDAs are equivalent in power: a CFG can be converted into a PDA (as shown in the example), and every PDA can be converted into an equivalent CFG by first transforming the PDA into conversion form. The conversion form imposes six strict structural rules (single ACCEPT, no REJECT, READ/HERE immediately followed by POP, no consecutive POPs without an intervening READ/HERE, branching only at READ/HERE, and a $ bottom-of-stack marker). The HERE state is introduced as a neutral state to insert between conflicting transitions (like consecutive POPs) to satisfy these conditions. For the exam, you must be able to modify a given PDA diagram to meet each of the six conversion form criteria.
🧠 Quick Revision Questions
- What is the purpose of converting a CFG into CNF before constructing its corresponding PDA?
- State the theorem discussed in this lecture regarding the relationship between PDAs and CFGs.
- What are the six conditions that a PDA must satisfy to be in conversion form?
- What is the role of the "HERE" state in the conversion process?
- Explain how condition 3 (every READ/HERE followed by a POP) modifies an existing PDA transition.
📘 Lecture 41 — Recap of PDA in conversion form, example of PDA in conversion form, joints of the machine, new pictorial representation of PDA in conversion form, summary table, row sequence, row language
📖 Overview: This lecture introduces the conversion form of a Pushdown Automaton (PDA), a standardized representation that simplifies analysis and language generation. It covers the strict conditions a PDA must satisfy to be in conversion form, demonstrates the conversion process with an example, and introduces the concepts of joints, summary tables, row sequences, and row language as tools for describing PDA behavior.
🗂️ Topics Covered
The lecture begins by defining the seven conditions for a PDA to be in conversion form. It then presents a concrete example of a PDA for the language {a²ⁿbⁿ : n = 1,2,3,...} and its conversion to conversion form. The concept of joints (START, READ, HERE, ACCEPT states) is introduced, along with their role in defining path segments. A summary table is constructed from the converted PDA, and the notion of row sequence is used to represent paths. Finally, row language is defined as the set of all joint-consistent and STACK-consistent row sequences.
📝 Lecture Summary
Conversion form of PDA
A PDA is in conversion form if it fulfills the following conditions:
- There is only one ACCEPT state.
- There are no REJECT states.
- Every READ or HERE is followed immediately by a POP — i.e. every edge leading out of any READ or HERE state goes directly into a POP state.
- No two POPs exist in a row on the same path without a READ or HERE between them whether or not there are any intervening PUSH states (i.e. the POP states must be separated by READs or HEREs).
- All branching, deterministic or nondeterministic occurs at READ or HERE states, none at POP states and every edge has only one label.
- Even before we get to START, a "bottom of STACK" symbol $ is placed on the STACK. If this symbol is ever popped in the processing it must be replaced immediately. The STACK is never popped beneath this symbol. Right before entering ACCEPT this symbol is popped out and left.
- The PDA must begin with the sequence START — POP — PUSH $ — READ. The entire input string must be read before the machine can accept the word.
🔑 Definition — Conversion Form of PDA: A standardized form of a PDA that satisfies seven strict conditions to ensure consistent structure for analysis and language generation.
Example
Consider the following PDA accepting the language {a²ⁿbⁿ : n = 1,2,3,...}:
[Pictorial representation shows states POP1, READ2, POP2, POP3 with transitions on a, b, Δ]
Which may be converted to:
[Converted PDA shows START → POP4 → PUSH$ → READ1 with transitions through POP5, POP6, READ2, POP1, POP2, POP3, HERE, and ACCEPT states]
The above PDA accepts exactly the same language.
💡 Why this matters: The conversion process preserves the language while making the PDA structure uniform and easier to analyze mathematically.
Note
It may be noted that any PDA which is in conversion form can be considered to be the collection of path segments, where each path segment is of the following form:
| FROM | TO | READ What | POP Exactly one STACK character | PUSH Any string onto the STACK |
|---|---|---|---|---|
| START | READ | No input | Any character | Any string |
| READ | READ | One letter | Any character | Any string |
| READ | HERE | One letter | Any character | Any string |
| READ | ACCEPT | One letter | Any character | Any string |
| HERE | READ | No input | Any character | Any string |
| HERE | HERE | No input | Any character | Any string |
| HERE | ACCEPT | No input | Any character | Any string |
START, READ, HERE and ACCEPT states are called the joints of the machine. Between two consecutive joints on a path exactly one character is popped and any number of characters can be pushed.
The PDA which is in the conversion form can be supposed to be the set of joints with path segments in between, similar to a TG.
The above entire machine can be described as a list of all joint-to-joint path segments, called summary table.
🔑 Definition — Joint: A state of a PDA in conversion form that serves as a connection point between path segments. Joints are START, READ, HERE, and ACCEPT states.
🔑 Definition — Path Segment: The transition between two consecutive joints where exactly one character is popped from the STACK and any number of characters may be pushed onto the STACK.
🔑 Definition — Summary Table: A table listing all joint-to-joint path segments of a PDA in conversion form, containing FROM, TO, READ, POP, and PUSH columns.
The PDA converted to the conversion form has the following summary table:
| FROM | TO | READ | POP | PUSH | ROW Number |
|---|---|---|---|---|---|
| START | READ1 | Λ | $ | $ | 1 |
| READ1 | READ1 | a | $ | a$ | 2 |
| READ1 | READ1 | a | a | aa | 3 |
| READ1 | HERE | b | a | -- | 4 |
| HERE | READ2 | Λ | a | -- | 5 |
| READ2 | HERE | b | a | -- | 6 |
| READ2 | ACCEPT | Λ | $ | -- | 7 |
Consider the word aaaabb. This word is accepted by the above PDA through the following path:
START → POP4 → PUSH$ → READ1 → POP6 → PUSH$ → PUSH a → READ1 → POP5 → PUSH a → PUSH a → READ1 → POP5 → PUSH a → PUSH a → READ1 → POP5 → PUSH a → PUSH a → READ1 → POP1 → HERE → POP2 → READ2 → POP1 → HERE → POP2 → READ2 → POP3 → ACCEPT
The above path can also be expressed by the following path in terms of sequence of rows:
Row1 – Row2 – Row3 – Row3 – Row3 – Row4 – Row5 – Row6 – Row5 – Row7
It can be observed that the above path is not only joint-to-joint consistent but STACK consistent as well.
It may be noted that in FAs, paths correspond to strings of letters, while in PDAs, paths correspond to strings of rows from the summary table.
🔑 Definition — Row Sequence: A sequence of row numbers from the summary table that represents a path through the PDA.
Note
It may be noted that since the HERE state reads nothing from the TAPE, therefore Λ is kept in the READ what column.
It may also be noted that the summary table contains all the information of the PDA which is in the pictorial representation. Every path through the PDA is a sequence of rows of the summary table. However, not every sequence of rows from the summary table represents a viable path, i.e. every sequence of rows may not be STACK consistent.
It is very important to determine which sequences of rows do correspond to possible paths through the PDA, because the paths are directly related to the language accepted, e.g. Row4 cannot be immediately followed by Row6 because Row4 leaves in HERE, while Row6 begins in Read2. Some information must be kept about the STACK before rows are concatenated.
To represent a path, a sequence of rows must be:
- Joint-consistent (the rows meet up end to end)
- STACK-consistent (when a row pops a character it should be there at the top of the STACK)
The next target is to define row language whose alphabet is Σ = {Row1, Row2, ..., Row7} i.e. the alphabet consists of the letters which are the names of the rows in the summary table.
🔑 Definition — Row Language: The language over the alphabet of row names whose words trace joint-to-joint and STACK-consistent paths through the PDA.
Note
It may be noted that the words of the row language trace joint-to-joint and STACK consistent paths, which shows that all the words of this language begin with Row1 and end in Row7.
Consider the following row sequence: Row5 Row5 Row3 Row6
This is string of 4 letters, but not a word of the row language because:
- It does not represent a path starting from START and ending in ACCEPT state.
- It is not joint consistent.
- It is not STACK consistent.
Before the CFG that generates the language accepted by the given PDA is determined, the CFG that generates the row language is to be determined. For this purpose new nonterminals are to be introduced that contain the information needed to ensure joint and STACK consistency.
It is not needed to maintain any information about what characters are read from the TAPE.
⭐ Key Takeaways
The conversion form of a PDA imposes seven strict conditions that standardize the machine's structure, making it possible to represent all paths as sequences of rows from a summary table. The key insight is that each path segment between joints (START, READ, HERE, ACCEPT) pops exactly one character and pushes any number, and these segments are cataloged in the summary table with row numbers. Not every sequence of rows is valid — a sequence must be both joint-consistent (consecutive rows connect properly) and STACK-consistent (the character popped is at the top of the stack). The row language consists of all valid row sequences that begin with Row1 and end with Row7, directly corresponding to accepted input strings. Understanding row sequences and row language is the critical precursor to constructing a CFG that generates the language accepted by the PDA.
🧠 Quick Revision Questions
- What are the seven conditions a PDA must satisfy to be in conversion form?
- What is a joint in a PDA in conversion form, and what are the four types of joints?
- How is the summary table constructed from a PDA in conversion form, and what information does each row contain?
- Explain the difference between joint consistency and STACK consistency for a sequence of rows.
- Why is the row sequence "Row5 Row5 Row3 Row6" not a valid word of the row language, and what two conditions does it violate?
📘 Lecture 42 — Row Language, Nonterminals Defined from Summary Table, Productions Defined by Rows, Rules for Defining Productions, All Possible Productions of CFG for Row Language of the Example Under Consideration, CFG Corresponding to the Given PDA
📖 Overview: This lecture explains how to construct a Context-Free Grammar (CFG) for the row language derived from a PDA’s summary table. It defines nonterminals, introduces production rules based on STACK behavior, and demonstrates the complete CFG for the PDA accepting the language {a²ⁿ bⁿ}. This bridges the gap between PDA behavior and formal grammar generation.
🗂️ Topics Covered
The lecture covers the concept of row language and the use of Net(X, Y, Z) nonterminals to represent path segments between joints. It defines how to determine true Net sentences by examining summary table rows, then provides three formal rules for generating CFG productions from those rows. Finally, it lists all possible productions for the example PDA and shows a leftmost derivation of a shortest word.
📝 Lecture Summary
Row Language and Nonterminals Defined from Summary Table
The row language has an alphabet Σ = {Row₁, Row₂, ..., Row₇} for the example PDA. Nonterminals are introduced in the form Net(X, Y, Z), where X and Y are joint states and Z is any STACK character. A Net(X, Y, Z) represents a path segment between two joints such that the net STACK effect is the same as popping Z. Not all such sentences are true; each row of the summary table is examined to determine whether the net effect of popping is exactly one letter.
🔑 Definition — Net sentence: A sequence of rows in the summary table where the net effect on the STACK is to pop exactly one character, represented by the nonterminal Net(X, Y, Z).
📌 Example: Consider Row₄ from the PDA for {a²ⁿ bⁿ}:
| FROM Where | TO Where | READ What | POP What | PUSH What | ROW Number |
|---|---|---|---|---|---|
| READ₁ | HERE | b | a | -- | 4 |
The nonterminal corresponding to this row is Net(READ₁, HERE, a), meaning Row₄ itself is a single Net row.
Productions Defined by Rows
If a row pushes multiple characters onto the STACK, it cannot itself be a Net sentence. Instead, such rows can be concatenated with other Net sentences. For example, an arbitrary row:
| FROM Where | TO Where | READ What | POP What | PUSH What | ROW Number |
|---|---|---|---|---|---|
| READ₉ | READ₃ | b | b | abb | 11 |
Row₁₁ is not a Net sentence because it pops one b but pushes two letters (a, b, b), adding net two letters. However, Row₁₁ can be concatenated as:
Row₁₁ Net(READ₃, READ₇, a) Net(READ₇, READ₁, b) Net(READ₁, READ₈, b)
This gives the nonterminal Net(READ₉, READ₈, b), leading to the production:
Net(READ₉, READ₈, b) → Row₁₁ Net(READ₃, READ₇, a) Net(READ₇, READ₁, b) Net(READ₁, READ₈, b)
Three Rules for Defining All Possible Productions of CFG for Row Language
Rule 1: The trip from START to ACCEPT with net effect Net(START, ACCEPT, $) gives the production:
S → Net(START, ACCEPT, $)
Rule 2: For any row that pops a single character and pushes nothing (i.e., — in PUSH column):
| FROM Where | TO Where | READ What | POP What | PUSH What | ROW Number |
|---|---|---|---|---|---|
| X | Y | anything | z | -- | i |
The production is:
Net(X, Y, z) → Rowᵢ
Rule 3: For any row that pushes a string of characters onto the STACK:
| FROM Where | TO Where | READ What | POP What | PUSH What | ROW Number |
|---|---|---|---|---|---|
| READₓ | READᵧ | u | w | m₁m₂...mₙ | i |
Then for any sequence of joint states S₁, S₂, ... Sₙ, the production is:
Net(READₓ, Sₙ, w) → Rowᵢ Net(READᵧ, S₁, m₁) Net(S₁, S₂, m₂) ... Net(Sₙ₋₁, Sₙ, mₙ)
💡 Why this matters: This rule introduces new productions, but not every production necessarily leads to a word in the language.
All Possible Productions of CFG for Row Language of the Example Under Consideration
For the PDA accepting {a²ⁿ bⁿ}, using rules 1, 2, and 3:
Rule 1:
S → Net(START, ACCEPT, $)
Rule 2 (from rows that pop exactly one letter):
Net(READ₁, HERE, a) → Row₄
Net(HERE, READ₂, a) → Row₅
Net(READ₂, HERE, a) → Row₆
Net(READ₂, ACCEPT, $) → Row₇
Rule 3 (from Row₁ — READ₁, pops $, pushes $):
Net(START, READ₁, $) → Row₁ Net(READ₁, READ₁, $)
Net(START, READ₂, $) → Row₁ Net(READ₁, READ₂, $)
Net(START, HERE, $) → Row₁ Net(READ₁, HERE, $)
Net(START, ACCEPT, $) → Row₁ Net(READ₁, ACCEPT, $)
Rule 3 (from Row₂ — pushes a$):
Net(READ₁, READ₁, $) → Row₂ Net(READ₁, READ₁, a) Net(READ₁, READ₁, $)
Net(READ₁, READ₁, $) → Row₂ Net(READ₁, READ₂, a) Net(READ₂, READ₁, $)
Net(READ₁, READ₁, $) → Row₂ Net(READ₁, HERE, a) Net(HERE, READ₁, $)
Net(READ₁, READ₂, $) → Row₂ Net(READ₁, READ₁, a) Net(READ₁, READ₂, $)
Net(READ₁, READ₂, $) → Row₂ Net(READ₁, READ₂, a) Net(READ₂, READ₂, $)
Net(READ₁, READ₂, $) → Row₂ Net(READ₁, HERE, a) Net(HERE, READ₂, $)
Net(READ₁, HERE, $) → Row₂ Net(READ₁, READ₁, a) Net(READ₁, HERE, $)
Net(READ₁, HERE, $) → Row₂ Net(READ₁, READ₂, a) Net(READ₂, HERE, $)
Net(READ₁, HERE, $) → Row₂ Net(READ₁, HERE, a) Net(HERE, HERE, $)
Net(READ₁, ACCEPT, $) → Row₂ Net(READ₁, READ₁, a) Net(READ₁, ACCEPT, $)
Net(READ₁, ACCEPT, $) → Row₂ Net(READ₁, READ₂, a) Net(READ₂, ACCEPT, $)
Net(READ₁, ACCEPT, $) → Row₂ Net(READ₁, HERE, a) Net(HERE, ACCEPT, $)
Rule 3 (from Row₃ — pushes aa):
Net(READ₁, READ₁, a) → Row₃ Net(READ₁, READ₁, a) Net(READ₁, READ₁, a)
Net(READ₁, READ₁, a) → Row₃ Net(READ₁, READ₂, a) Net(READ₂, READ₁, a)
Net(READ₁, READ₁, a) → Row₃ Net(READ₁, HERE, a) Net(HERE, READ₁, a)
Net(READ₁, READ₂, a) → Row₃ Net(READ₁, READ₁, a) Net(READ₁, READ₂, a)
Net(READ₁, READ₂, a) → Row₃ Net(READ₁, READ₂, a) Net(READ₂, READ₂, a)
Net(READ₁, READ₂, a) → Row₃ Net(READ₁, HERE, a) Net(HERE, READ₂, a)
Net(READ₁, HERE, a) → Row₃ Net(READ₁, READ₁, a) Net(READ₁, HERE, a)
Net(READ₁, HERE, a) → Row₃ Net(READ₁, READ₂, a) Net(READ₂, HERE, a)
Net(READ₁, HERE, a) → Row₃ Net(READ₁, HERE, a) Net(HERE, HERE, a)
Net(READ₁, ACCEPT, a) → Row₃ Net(READ₁, READ₁, a) Net(READ₁, ACCEPT, a)
Net(READ₁, ACCEPT, a) → Row₃ Net(READ₁, READ₂, a) Net(READ₂, ACCEPT, a)
Net(READ₁, ACCEPT, a) → Row₃ Net(READ₁, HERE, a) Net(HERE, ACCEPT, a)
CFG Corresponding to the Given PDA
Rule 4 completes the CFG by converting each row into a terminal symbol. Each row of the summary table defines a production of the form Rowᵢ → a, where in Rowᵢ the READ column consists of the letter a.
For the example PDA accepting {a²ⁿ bⁿ}, Rule 4 adds:
Row₁ → Λ
Row₂ → a
Row₃ → a
Row₄ → b
Row₅ → Λ
Row₆ → b
Row₇ → Δ
This means the row language word Row₁ Row₂ Row₃ Row₄ Row₅ Row₇ is converted to:
Λ a a b Λ Δ = a a b = aab
Which corresponds to the PDA word aab (i.e., a² b¹).
Leftmost derivation of the shortest word:
S ⇒ Net(START, ACCEPT, $) ... using 1
⇒ Row₁ Net(READ₁, ACCEPT, $) ... using 9
⇒ Row₁ Row₂ Net(READ₁, READ₂, a) Net(READ₂, ACCEPT, $) ... using 20
⇒ Row₁ Row₂ Row₃ Net(READ₁, HERE, a) Net(READ₂, HERE, a) Net(READ₂, ACCEPT, $) ... using 27
⇒ Row₁ Row₂ Row₃ Row₄ Net(HERE, READ₂, a) Net(READ₂, ACCEPT, $) ... using 2
⇒ Row₁ Row₂ Row₃ Row₄ Row₅ Net(HERE, ACCEPT, $) ... using 3
⇒ Row₁ Row₂ Row₃ Row₄ Row₅ Row₇ ... using 5
This yields the shortest word Row₁ Row₂ Row₃ Row₄ Row₅ Row₇ in the whole row language.
⭐ Key Takeaways
The most critical points to remember: (1) Net(X, Y, Z) nonterminals represent path segments whose net STACK effect is popping exactly one character Z between joints X and Y. (2) Three rules generate all CFG productions: Rule 1 gives the start symbol S → Net(START, ACCEPT, $); Rule 2 handles rows that pop one character and push nothing; Rule 3 handles rows that push strings, creating concatenations of Net nonterminals. (3) Rule 4 converts each Rowᵢ to a terminal letter from the READ column, allowing row language words to generate actual PDA-accepted words. (4) Not every production necessarily leads to a word; the system generates all possibilities, and only joint-consistent and STACK-consistent derivations yield valid words. (5) The complete CFG for the example PDA shows that the shortest word Row₁ Row₂ Row₃ Row₄ Row₅ Row₇ corresponds to the string aab of the original language.
🧠 Quick Revision Questions
- What does Net(READ₁, HERE, a) represent in terms of STACK behavior and joint states?
- Under what condition does a row in the summary table yield a single Net sentence (Rule 2)?
- When applying Rule 3, why must the sequence of joint states S₁, S₂, ... Sₙ be arbitrary?
- The shortest word in the row language for {a²ⁿ bⁿ} is Row₁ Row₂ Row₃ Row₄ Row₅ Row₇. What is the corresponding word in the original language after applying Rule 4?
- Why does the leftmost derivation shown produce exactly the shortest word in the row language? What constraints ensure no shorter derivation exists?
📘 Lecture 43 — Non-Context-Free Languages and Pumping Lemma for CFLs
📖 Overview: This lecture establishes that not all languages are Context-Free, introducing the concept of Non-Context-Free Languages. It presents the Pumping Lemma for Context-Free Languages as a tool to prove that certain languages are not CFLs, along with live and dead productions, self-embedded nonterminals, and detailed examples demonstrating how to apply the lemma.
🗂️ Topics Covered
The lecture covers Non-Context-Free languages, live productions (nonterminal → two nonterminals) and dead productions (nonterminal → terminal), a theorem about finite word generation in CNF grammars, the self-embedded nonterminal concept, the Pumping Lemma for CFLs with its proof and applications, examples showing how to apply the lemma to languages like {aⁿbⁿcⁿ} and {aⁿbᵐaⁿbᵐ}, a comparison with the Pumping Lemma for regular languages, and the second version of the Pumping Lemma for CFLs with a worked example of the EVENA language grammar conversion.
📝 Lecture Summary
Non-Context-Free language
Not all languages are Context-Free. Languages that are not Context-Free are called Non-CFL. To prove this claim, we need to study how words are produced from grammars.
🔑 Definition — Non-CFL: A language that cannot be generated by any Context-Free Grammar.
Live production & Dead production
A live production is a production of the form nonterminal → string of two nonterminals. A dead production is a production of the form nonterminal → terminal. Every CFG in Chomsky Normal Form (CNF) has only these types of productions.
Theorem
If a CFG is in CNF and there is a restriction to use each live production at most once, then only finite many words can be generated. Every time a live production is applied during derivation, it increases the number of nonterminals by one. Applying a dead production decreases nonterminals by one. To generate a word, one more dead production is applied than live productions.
Example: S → XY → aY → aa Here one live production (S→XY) and two dead productions (X→a, Y→a) are used.
📐 Formula: If a CFG in CNF has p live and q dead productions, then all words generated without repeating any live production have at most (p+1) letters.
Theorem
If a CFG is in CNF with p live and q dead productions, and w is a word generated by the CFG having more than 2^p letters, then any derivation tree for w has a nonterminal z which is used twice, where the second z is descended from the first z. The generation tree of word w has more than p rows.
Self-embedded nonterminal
A self-embedded nonterminal occurs when, in a given derivation of a word, a nonterminal ever occurs as a tree descendant of itself.
🔑 Definition — Self-embedded nonterminal: A nonterminal X is self-embedded if X → ... → ...X... appears in the derivation tree, meaning X produces a string that eventually yields another X.
Example with grammar: S → AB, A → BC, C → AB, A → a, B → b For word bbabbb, the derivation tree shows A is self-embedded. The part of tree in the upper triangle is identical to that in the lower triangle, allowing replacement of A by the same sequence of productions.
💡 Why this matters: Self-embedded nonterminals are the key to deriving infinite sets of words and form the basis for the pumping lemma.
Pumping lemma for CFLs
Theorem: If G is any CFG in CNF with p live productions, then every word w of length more than 2^p can be partitioned into five substrings as w = uvxyz, where x is not null string and v and y are not both null string. Then all words of the form uvⁿxyⁿz, n = 1,2,3,... can also be generated by G.
Example: Consider CFG in CNF: S → PQ, Q → QS|b, P → a, and word abab. The derivation tree shows: u = a, v = λ, x = b, y = ab, z = λ Repeating the triangle from the second Q descending from the first Q gives uvvxyyz = aλλbababλ = ababab Thus words of form uvⁿxyⁿz belong to the language.
Note
The pumping lemma is satisfied by all CFLs. Languages that don't hold this pumping lemma cannot be Context-Free — such languages are non-CFLs.
Example: Consider L = {aⁿbⁿcⁿ : n=1,2,3,...}. Let w = a²⁰⁰b²⁰⁰c²⁰⁰ (length > 2^p). No matter what choices are made for u,v,x,y,z, uv²xy²z cannot belong to L because all words in aⁿbⁿcⁿ have:
- Only one substring ab
- Only one substring bc
- No substring ac, ba, ca, or cb
If v or y is not a single letter or λ, then uv²xy²z may contain two or more substrings ab or bc. If v and y are single letters or λ, then one or two of letters a,b,c will be increased while the others remain unchanged. Thus pumping lemma is not satisfied, so L is non-CFL.
Comparison with Pumping Lemma for Regular Languages
The pumping lemma for infinite regular languages decomposes w into three parts (w=xyz) such that xyⁿz belong to L. The pumping lemma for CFLs decomposes w into five parts (w=uvxyz) such that uvⁿxyⁿz belong to L.
The proof for regular languages requires a path long enough to contain a circuit. The proof for CFLs requires a derivation long enough to contain a sequence of productions that can be repeated. The regular language pumping lemma acts on machines (FA), while the CFL pumping lemma acts on algebraic structures (grammars).
Second Version of Pumping Lemma
Theorem: If L is a CFL in CNF with p live productions, then any word w in L of length more than 2^p can be decomposed as w = uvxyz such that:
- length(vxy) ≤ 2^p
- length(x) > 0
- length(v) + length(y) > 0 Then words of the form uvⁿxyⁿz : n=1,2,3,... belong to L.
Example: Consider L = {aⁿbᵐaⁿbᵐ : m,n=1,2,3,...} = {abab, aabaab, abbabb, aabbaabb, ...}. The first version of pumping lemma may be satisfied, but applying the second version: let w be decomposed into uvxyz where length(vxy) < 2^p. This shows v and y can't be single letters separated by clumps of other letters (separator letter longer than vxy), so uvvxyyz is not in L. Thus L is non-CFL.
Example — EVENA language: EVENA = (aa)ⁿ = a²ⁿ = {aa, aaaa, aaaaaa, ...}. Grammar: S → SS|aa. CNF: S → SS|AA, A → a. A PDA is constructed, converted to conversion form, and a summary table with 9 rows is created. From the summary table, 44 productions are defined plus 9 row productions completing the CFG.
📐 Formula: Net(START, ACCEPT, $) → productions defined from summary table rows, where X and Y are corresponding joints.
⭐ Key Takeaways
The most critical points to remember: Non-Context-Free languages exist and cannot be generated by any CFG. The Pumping Lemma for CFLs states that for any CFL G in CNF with p live productions, every word longer than 2^p can be written as uvxyz, and all uvⁿxyⁿz belong to the language. A self-embedded nonterminal (one that appears as a descendant of itself in the derivation tree) is essential for infinite language generation. To prove a language is non-CFL, show it violates the pumping lemma — like aⁿbⁿcⁿ where pumping either creates extra substrings or unbalanced letter counts. The second version of the lemma adds the constraint length(vxy) ≤ 2^p, making it more powerful for proving non-CFL status, as demonstrated with aⁿbᵐaⁿbᵐ.
🧠 Quick Revision Questions
- What is the difference between a live production and a dead production in CNF, and how many of each are needed to generate a word?
- State the Pumping Lemma for CFLs and explain why the word a²⁰⁰b²⁰⁰c²⁰⁰ cannot satisfy it for the language {aⁿbⁿcⁿ}.
- What is a self-embedded nonterminal and why is it crucial to the proof of the Pumping Lemma for CFLs?
- In the second version of the Pumping Lemma for CFLs, what additional constraints are placed on the decomposition w = uvxyz, and why are these constraints important?
- For the language L = {aⁿbᵐaⁿbᵐ}, explain step by step why the second version of the Pumping Lemma shows it is not a CFL.
📘 Lecture 44 — Decidability, Parsing Techniques
📖 Overview: This lecture addresses decidability problems for Context-Free Grammars (CFGs), providing algorithms to determine emptiness, finiteness, and membership. It also introduces parsing techniques, particularly top-down parsing, with detailed examples using the PLUS-TIMES grammar to demonstrate how derivations are constructed.
🗂️ Topics Covered
Decidability problems for CFGs including emptiness (whether a CFG generates any word), uselessness (whether a nonterminal is used in derivation), finiteness (whether a CFL is finite), and membership (whether a given string is generated). Algorithms for each problem are presented with examples. The lecture concludes with parsing techniques, focusing on top-down parsing with the PLUS-TIMES grammar.
📝 Lecture Summary
Decidability
The following are decidable problems with respect to CFG:
- Whether or not the given CFG generates any word? — Problem of emptiness of CFL.
- Whether or not the given CFG generates the finite language? — Problem of finiteness.
- Whether or not the given string w can be generated by the given CFG? — Problem of membership.
Three algorithms show that the answers to these questions are yes.
Algorithm 1 (Emptiness)
If the given CFG contains a production of the form S → Λ, then the corresponding CFL is not empty. If the CFG contains a production of the form S → t, where t is a terminal or string of terminals, then t is a word of the corresponding CFL and the CFL is not empty.
If the CFG contains no such production:
- For each nonterminal N with N → t, pick one production for N (if there are more than one) and replace N by t in the right side of each production wherever it appears.
- Remove all such productions from the CFG.
- Repeat the process until either S is eliminated or no new nonterminal is eliminated.
If S has been eliminated, the CFG generates some words; otherwise not.
📌 Example:
S → AB, A → BSB, B → CC
C → SS
A → a|b
C → b|bb
Step (1): Pick A → a, C → b:
S → aB
A → BSB
A → bb
B → aaS
B → bb
C → SS
Step (2): Pick B → bb and A → bb:
S → abb
A → bbSbb
B → aaS
C → SS
Since S → abb has been obtained, abb is a word in the corresponding CFL.
💡 Why this matters: This algorithm provides a systematic method to determine if a CFG produces any terminal strings at all, which is the first question to ask about any grammar.
Algorithm 2 (Uselessness)
To determine whether a nonterminal X is ever used in the derivation of a word from the given CFG:
- Find all unproductive nonterminals (a nonterminal that cannot produce a string of terminals).
- Eliminate all productions involving unproductive nonterminals.
- Paint all X's blue.
- If any nonterminal is on the left side of a production with any blue nonterminal in the right side, paint that nonterminal blue at all occurrences throughout the grammar.
- Repeat step 4 until no new nonterminal is painted.
- If S is blue, then X is a useful member of the CFG; otherwise not.
🔑 Definition — Useless: A nonterminal is called useless if it cannot be used in a production of some word.
📌 Example: Consider the CFG:
S → Aba | bAZ | b
A → Xb | bZa
B → bAA
X → aZa | aaa
Z → ZAbA
To determine whether X is ever used: First, Z is unproductive. Eliminating productions involving Z:
S → Aba | b
A → Xb
B → bAA
X → aaa
X is blue → A is blue → B and S are blue. Since S is blue, X can be used to generate certain words from the given CFG.
💡 Why this matters: Many CFGs contain nonterminals that appear in productions but can never actually contribute to generating terminal strings. This algorithm identifies and removes such useless symbols.
Algorithm 3 (Finiteness)
To determine whether the given CFG generates a finite language:
- Determine all useless nonterminals and eliminate all productions involving them.
- For each remaining nonterminal, determine whether they are self-embedded.
- Stop if a self-embedded nonterminal is discovered.
To test whether X is self-embedded:
- (a) Change all X's on the left side of productions into a Greek letter Ψ and keep all X's on the right side as such.
- (b) Paint all X's blue.
- (c) If Y is any nonterminal on the left side of a production with X in the right side, paint Y blue.
- (d) Repeat step (c) until no new nonterminal is painted.
- (e) If Ψ is painted, then X is self-embedded; otherwise not.
If any nonterminal left in the grammar after step 1 is self-embedded, then the language generated is infinite; otherwise finite.
📌 Example: Consider the CFG:
S → ABa | bAZ | b
A → Xb | bZa
B → bAA
X → aZa | bA | aaa
Z → ZAbA
Nonterminal Z is useless. Eliminating productions involving Z:
S → ABa | b
A → Xb
B → bAA
X → bA | aaa
Starting with nonterminal X: Replace X on the left side by Ψ:
S → ABa | b
A → Xb
B → bAA
Ψ → bA | aaa
X is blue → A is blue → Ψ is blue. Since A is blue → B is blue → S is blue. Since Ψ is blue, X is self-embedded, and the CFG generates an infinite language.
💡 Why this matters: Self-embedded nonterminals create recursive structures that allow strings of unbounded length, making languages infinite. This is crucial for understanding language properties.
Algorithm 4 (The CYK Algorithm)
This algorithm was invented by John Cocke and later published by Tandao Kasami and Daniel H. Younger.
- Convert the given CFG to CNF (Chomsky Normal Form).
- Let the string x have the form x = x₁x₂x₃...xₙ where all xᵢ's may not be different.
- List all nonterminals in the given CFG (e.g., S, N₁, N₂, ...).
- List nonterminals that generate single-letter substrings of x.
- List nonterminals that generate substrings of length 2.
- Continue listing for substrings of length 3, 4, ..., n.
- If S is among the set of all producing nonterminals for x₁x₂x₃...xₙ, then x can be generated; otherwise not.
📌 Example: Consider the CFG in CNF:
S → AA
A → AA
A → a
Let x = aaa (x₁ = x₂ = x₃ = a).
According to the CYK algorithm:
| Substring | All producing nonterminals |
|---|---|
| x₁ = a | A |
| x₂ = a | A |
| x₃ = a | A |
| x₁x₂ | S, A |
| x₂x₃ | S, A |
| x = x₁x₂x₃ | S, A |
Since S is in the list of producing nonterminals, aaa can be generated by the given CFG.
Parsing Techniques
Recall the CFG for arithmetic expression:
S → S+S | S*S | number
The word 3+4*5 created ambiguity (value either 23 or 35). To remove this ambiguity, the CFG was modified with parentheses. A new CFG can be defined without parentheses using operator hierarchy (* before +). The PLUS-TIMES grammar is:
S → E
E → T+E | T
T → F*T | F
F → (E) | i
Where i stands for any identifier (number or variable name).
📌 Derivation of i+i*i:
S ⇒ E ⇒ T+E ⇒ F+E ⇒ i+E ⇒ i+T ⇒ i+F*T ⇒ i+i*T ⇒ i+i*F ⇒ i+i*i
🔑 Definition — Parsing: The process of finding the derivation of a word generated by a particular grammar is called parsing.
There are different parsing techniques, including:
- Top-down parsing
- Bottom-up parsing
- Parsing technique for particular grammar of arithmetic expression
Top-Down Parsing
In top-down parsing, parsing starts from the nonterminal S and develops a structure similar to the total language tree. The branches of the tree are extended until the required word is found as a branch. Unwanted branches (those that don't lead to the required word) are dropped.
📌 Example (PLUS-TIMES grammar, word i+i*i):
Starting from S, the tree branches:
S
├── E
├── T+E
│ ├── F*T+E → (E)*T+E (branch 1) → drop
│ ├── F+E → (E)+E (branch 3) → drop
│ └── ...
├── T (branch to T without +E)
└── ...
After dropping unwanted branches (1, 3, 5, 7, and 8), the tree shows:
S
└── E
├── T+E
│ ├── F*T+E → i*T+E (branch 2) → drop (first two letters don't match i+i*i)
│ └── F+E → i+E (branch 4)
└── T → F*T → i*T (branch 6) → drop
From branch (4) using leftmost derivation:
i+E → i+T+E (branch 9) → drop (more than five letters)
→ i+T
→ i+F*T+E (branch 10) → drop (contains two +)
→ i+F*T
→ i+(E)*T (branch 13) → drop
→ i+i*T
→ i+i*F*T (continue) → i+i*(E) → drop
→ i+i*F → i+i*i ✓
The tree confirms the required derivation:
S ⇒ E ⇒ T+E ⇒ F+E ⇒ i+E ⇒ i+T ⇒ i+F*T ⇒ i+i*T ⇒ i+i*F ⇒ i+i*i
💡 Why this matters: Top-down parsing provides a systematic tree-based approach to finding derivations, which is fundamental to compiler design and natural language processing.
⭐ Key Takeaways
The key concepts from this lecture are the four decidability algorithms for CFGs: the emptiness algorithm determines if any word is generated by repeatedly replacing nonterminals with terminal strings until S is eliminated; the uselessness algorithm identifies nonterminals that can never contribute to word generation by painting connected nonterminals and checking if S is painted; the finiteness algorithm tests for self-embedded nonterminals (which indicate infinite language generation) by replacing left-side occurrences of a nonterminal with a Greek letter and checking if that letter gets painted through connections; and the CYK membership algorithm works on CNF grammars by building a table of nonterminals that generate all substrings of increasing length. Additionally, top-down parsing begins from the start symbol S and builds a derivation tree downward until the target string is found, dropping branches that cannot lead to the desired word.
🧠 Quick Revision Questions
-
What are the three decidability problems for CFGs mentioned in this lecture?
-
In the emptiness algorithm, what condition indicates that a CFG generates at least one word?
-
How do you determine whether a nonterminal X is useful or useless in a CFG?
-
What does it mean for a nonterminal to be self-embedded, and what does it imply about the language generated?
-
In the CYK algorithm, what condition must be satisfied for the given string to be generated by the CFG?
📘 Lecture 45 — Theory of Automata
📖 Overview: This lecture introduces the Turing machine (TM), a more powerful computational model capable of accepting non-context-free languages like (a^n b^n a^n) alongside regular languages. It also covers practical TM subprograms for inserting and deleting characters on the tape, which are essential for manipulating string data in computations.
🗂️ Topics Covered
This lecture covers the definition and components of a Turing machine, including its infinite tape, tape head, alphabet, states, and program rules. It provides examples of TMs for regular languages like EVEN-EVEN and non-CFLs like (a^n b^n a^n). The lecture then details the INSERT subprogram for adding a character at the tape head’s location, shifting the rest right, and the DELETE subprogram for removing a character and shifting the rest left.
📝 Lecture Summary
Turing machine
The mathematical models (FAs, TGs, PDAs) that have been discussed so far can decide whether a string is accepted or not by them i.e. these models are language identifiers. However, there are still some languages which can’t be accepted by them e.g. there does not exist any FA or TG or PDA accepting any non-CFLs. Alan Mathison Turing developed the machines called Turing machines, which accept some non-CFLs as well, in addition to CFLs.
🔑 Definition — Turing machine (TM): consists of the following: An alphabet Σ of input letters. An input TAPE partitioned into cells, having infinite many locations in one direction. The input string is placed on the TAPE starting its first letter on the cell i, the rest of the TAPE is initially filled with blanks (Δ’s). A tape Head can read the contents of cell on the TAPE in one step. It can replace the character at any cell and can reposition itself to the next cell to the right or to the left of that it has just read. Initially the TAPE Head is at the cell i. The TAPE Head can’t move to the left of cell i. An alphabet Γ of characters that can be printed on the TAPE by the TAPE Head. Γ may include the letters of Σ. Even the TAPE Head can print blank Δ, which means to erase some character from the TAPE. Finite set of states containing exactly one START state and some (maybe none) HALT states that cause execution to terminate when the HALT states are entered. A program which is the set of rules, which show that which state is to be entered when a letter is read from the TAPE and what character is to be printed. This program is shown by the states connected by directed edges labeled by triplet (letter, letter, direction). The first letter is the character the TAPE Head reads from the cell to which it is pointing. The second letter is what the TAPE Head prints the cell before it leaves. The direction tells the TAPE Head whether to move one cell to the right, R, or one cell to the left, L.
Note: There may not be any outgoing edge at certain state for certain letter to be read from the TAPE, which creates nondeterminism in Turing machines. The machine crashes if there is not path for a letter to be read from the TAPE and the corresponding string is supposed to be rejected. To terminate execution of certain input string successfully, a HALT state must be entered and the corresponding string is supposed to be accepted by the TM. The machine also crashes when the TAPE Head is instructed to move one cell to the left of cell i.
🔑 Definition — acceptance by TM: The string is accepted if the TM enters a HALT state during its execution.
📐 Formula — TM transition: (read, print, direction) → meaning: if the tape head reads a specific character, print another character, then move one cell R (right) or L (left).
📌 Example: Consider the following Turing machine program. START state 1 has edges: (a,a,R) → state 2, (b,b,R) → state 3. State 2 has: (a,a,R) → state 2, (b,b,R) → state 3, (Δ,Δ,R) → HALT state 4. State 3 has: (a,a,R) → state 3, (b,b,R) → state 2. Let the input string aba be run over this TM. Starting from START state, reading 'a' → print 'a', move right → state 2. At state 2, reading 'b' → print 'b', move right → state 3. At state 3, reading 'a' → print 'a', stay in state 3. Then reading blank 'Δ' → print 'Δ', move right → HALT state. This shows that the string aba is accepted by this machine. The machine accepts the language expressed by (a+b)b(a+b)*.
Theorem
Every regular language is accepted by some TM.
📌 Example: Consider the EVEN-EVEN language. A TM accepting the EVEN-EVEN language is given, and its diagram is similar to that of FA corresponding to EVEN-EVEN language. Following is another example. Consider the following TM: START state 1 has (a,a,R) → state 2, (b,b,R) → state 3. State 2 has (a,a,R) → state 2, (b,b,R) → state 3, (Δ,Δ,R) → state 4. State 3 has (a,a,R) → state 3, (b,b,R) → state 2, (Δ,Δ,R) → state 4. State 4 has (a,a,R) → state 4, (b,b,R) → state 4, (Δ,Δ,R) → HALT state 5. The string aaabbbaaa can be observed to be accepted by the above TM. It can also be observed that the above TM accepts the non-CFL (a^n b^n a^n).
INSERT subprogram
Sometimes, a character is required to be inserted on the TAPE exactly at the spot where the TAPE Head is pointing, so that the character occupies the required cell and the other characters on the TAPE are moved one cell right. The characters to the left of the pointed cell are also required to remain as such. The subprogram of insertion is independent and can be incorporated at any time with any TM program specifying what character to be inserted at what location.
📌 Example: If the letter b is to be inserted at the cell where the TAPE Head is pointing as shown: Tape: b X a b b X Δ Δ. The tape head is at the cell containing 'a'. After insertion of b, the tape becomes: b X b a b b X Δ Δ. The function of subprogram INSERT b uses a marker Q placed temporarily. The algorithm: 1) At state 1, read the character at insertion point (e.g., 'a' or 'b' or 'X'). 2) Replace it with Q and move right, entering a state that remembers the displaced character (e.g., state 2 for 'a'). 3) Continue shifting each subsequent character one step right, remembering the displaced character from the previous cell, until a blank Δ is reached. 4) Replace the blank with the last displaced character. 5) Then move left, replacing 'Q' with the original inserted character ('b'), and move right one step.
🔑 Definition — INSERT subprogram: A TM subroutine that places a new character at the tape head's current cell, shifting all characters to the right by one cell.
DELETE subprogram
Sometimes, a character is required to be DELETED on the TAPE exactly at the spot where the TAPE Head is pointing, so that the other characters on the right of the TAPE Head are moved one cell left. The characters to the left of the pointed cell are also required to remain as such. The subprogram of deletion is independent and can be incorporated at any time with any TM program specifying what character to be deleted at what location.
📌 Example: If the letter a is to be deleted from the string bcabbc, shown below: Tape: b c a b b c Δ Δ. The tape head is at the cell containing 'a'. After deletion, the tape becomes: b c b b c Δ Δ. The function of subprogram DELETE uses a marker X placed temporarily. The algorithm: 1) At state 1, read the character to be deleted (e.g., 'a') → replace it with Δ (blank) and move right. 2) Enter state 2 and continue moving right, shifting each character one step left (replacing the current cell's content with the next cell's content) until a blank Δ is reached. 3) When blank is read, move left to the cell before the blank. 4) Then, in state 3, continue moving left, replacing the blank in the final cell (the duplicate) with the appropriate character from the preceding cell, until the start of the deletion area is reached. 5) At the final step, replace 'X' (the marker) with the character that was shifted into its position.
🔑 Definition — DELETE subprogram: A TM subroutine that removes the character at the tape head's current cell, shifting all characters to the right by one cell to the left.
💡 Why this matters: The INSERT and DELETE subprograms demonstrate a fundamental capability of Turing machines: in-place string editing. This is analogous to how computers manipulate text or data structures, illustrating that TMs are a model for general computation, not just language recognition.
⭐ Key Takeaways
The Turing machine is a more powerful computational model than FAs or PDAs because it can accept non-context-free languages like (a^n b^n a^n), in addition to all regular languages. Understanding the TM's structure—an infinite tape, a read/write head, and a set of transition rules—is crucial, along with the concepts of acceptance via HALT states and rejection via crashes. The INSERT and DELETE subprograms are essential techniques for manipulating tape contents, allowing the TM to perform arbitrary data processing tasks. These subprograms are independent modules that can be reused in larger TM programs for string editing operations.
🧠 Quick Revision Questions
- What are the key components of a Turing machine?
- How does a Turing machine accept or reject an input string?
- Can you draw the TM for the language (a^n b^n a^n)?
- Describe the step-by-step process of the INSERT subprogram when a character is to be inserted into a non-empty tape.
- Explain what happens to the tape contents when the DELETE subprogram is executed to remove a character.