Lesson 19 works out which operations keep a language context-free. It gives one-rule grammar constructions for union, concatenation, and star, with the variable-renaming condition, then the counterexample showing that intersection fails and why its shape is forced by the one-stack budget, and the De Morgan derivation of the failure of complement together with a concrete witness. It proves closure under intersection with a regular language by a product construction, flagging the trap of advancing the finite component on a free move, and covers reversal and the restricted form of difference. It ends with the full closure table read as a diagnostic for classifying languages.
Subject: Theory of Computation · 115 slides · symbolic lesson
Open the interactive version of this deck · Homework for this lesson
Title
Theory of Computation · Lesson 19
The three regular operations still work, in one rule each. Intersection and complement do not — and the failures are as useful as the successes.
Objectives
Lesson 7 found the regular languages closed under every operation tried. This class is different, and the differences are diagnostic. By the end you can:
Warm-up
Discussion prompt
Before we open Context-Free Closure Properties: without looking back, what was the main idea of The Pumping Lemma for CFLs, and what could you do by the end of it that you could not do before?
Hint: One sentence for the idea, one for the skill. If the second one is blank, that is the part to revisit.
Answer:
Lesson 18 supplies the tool for proving that a language has no context-free grammar. It shows how Chomsky normal form bounds the height of a parse tree, so that a long string forces a repeated variable somewhere on a root-to-leaf path, then gives the five-piece statement with its three conditions and the crucial difference from the regular case: the short window may sit anywhere rather than at the front. It proves the lemma and points out where minimality of the parse tree is used, then works proofs for three matched counts, a block written twice, and nested inequalities, with explicit case analysis over the window positions. It covers closure arguments using a regular helper and why a context-free helper proves nothing, and ends by comparing the two pumping lemmas.
Section
Section 1
Concept
The definition is the same as in Lesson 7, applied to a larger class.
The context-free languages are closed under an operation when applying it to members always yields another member. Each property is a theorem needing a construction and a proof.
\[ L_1, L_2 \in \mathcal{CF} \;\Longrightarrow\; L_1 \circ L_2 \in \mathcal{CF} \]
What is new is that some of the theorems are false, and disproving them takes a counterexample rather than a construction.
Counterexample
Discussion prompt
The definition is the same as in Lesson 7, applied to a larger class.
That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.
Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.
Answer:
The context-free languages are closed under an operation when applying it to members always yields another member. Each property is a theorem needing a construction and a proof.
Intuition
The regular class was closed under everything tried. The reason it could be is worth recalling, because it fails here.
Closure under intersection came from the product construction: run two machines in lockstep on the same input. That works because a finite automaton's whole situation is one state, so a pair of situations is again one state.
A pushdown automaton's situation includes a stack. Running two in lockstep would need two stacks, and a machine with two stacks is strictly more powerful — it is the machine of Lesson 20. So the construction is unavailable.
\[ \text{two stacks} \;\Rightarrow\; \text{beyond this class} \]
Analogy
Discussion prompt
Explain Why this class behaves differently by analogy to something with no Theory of Computation in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.
Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.
Answer:
The regular class was closed under everything tried. The reason it could be is worth recalling, because it fails here.
Concept
Some properties are easy on the grammar side and some on the machine side. Choosing correctly is most of the work.
| Property | Proved with | Why |
|---|---|---|
| union | grammars | one alternative per language |
| concatenation | grammars | one rule joining two start variables |
| star | grammars | one self-recursive rule |
| intersection with a regular language | machines | a product with a finite automaton |
| intersection, complement | counterexamples | the properties are false |
The pattern is clear: operations that build a language suit grammars, and operations that restrict one suit machines — when they hold at all.
Discrimination
Sort into buckets
Sort these by Proved with, from memory, without looking back at Where each proof will live. Telling them apart on the spot is the skill; the table is only where the answer happens to be written down.
Ranking
Put in order
These are the steps of How to prove a closure property here, scrambled. Put them back in order before the next slide shows you.
Why: This is the order the recipe itself gives. Recalling the sequence without the slide in front of you is the difference between recognising the method and being able to run it — most of what goes wrong in practice is a step done out of turn.
Pattern
The same five-part shape as Lesson 7, with one extra step at the front.
Step five needs Lesson 18. Every failure in this lesson is proved by producing a language already known to be beyond the class.
Elimination
Eliminate the wrong options
Why can the product construction not be used to prove closure under intersection for this class?
3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.
Survives elimination: A
Why: The product construction pairs the situations of two machines. A pushdown automaton's situation includes its stack, so the product would have to track two stacks at once — and a two-stack machine recognizes strictly more than this class, so the result would not be a pushdown automaton.
Check
Think about what a product construction would need here.
Check your understanding
Why can the product construction not be used to prove closure under intersection for this class?
Answer: A
Why: The product construction pairs the situations of two machines. A pushdown automaton's situation includes its stack, so the product would have to track two stacks at once — and a two-stack machine recognizes strictly more than this class, so the result would not be a pushdown automaton.
Intuition
It is tempting to see the failures as gaps. They are more useful than that.
A closure failure separates this class from the regular one, and gives a proof technique: if a language's intersection with something simple escapes the class, the language itself does too.
Lesson 18 already used exactly this, intersecting a candidate with a regular pattern. That argument works because intersection with a regular language is closed while general intersection is not — the asymmetry is the tool.
\[ \text{closed with regular} \;+\; \text{not closed in general} \;=\; \text{a proof technique} \]
Explain it
Discussion prompt
Explain Failures are diagnostic to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.
Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.
Answer:
A closure failure separates this class from the regular one, and gives a proof technique: if a language's intersection with something simple escapes the class, the language itself does too.
Section
Section 2
Concept
Take grammars for both languages, rename their variables apart, and add a fresh start variable with one alternative each.
\[ S \to S_1 \;\mid\; S_2 \]
A derivation commits to one branch at the first step and stays there, since neither grammar mentions the other's variables. So the generated strings are exactly those of one grammar or the other.
The renaming is essential, exactly as disjoint state sets were in Lesson 7. Shared variable names would let derivations cross between the grammars and generate strings in neither language.
\[ V_1 \cap V_2 = \varnothing \]
Ranking
Put in order
Put the moves of Prove closure under union into the order they have to happen.
Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. Rename variables apart, take the union of the rule sets, and add the fresh start variable with two alternatives.
Worked example
The construction and both inclusions, in full — it is short enough to do properly.
Build the grammar
Why: Rename variables apart, take the union of the rule sets, and add the fresh start variable with two alternatives.
\[ G = (V_1 \cup V_2 \cup \{S\}, \; \Sigma, \; R_1 \cup R_2 \cup \{S \to S_1, S \to S_2\}, \; S) \]
Show every string of the union is generated
Why: A string in the first language has a derivation from the first start variable. Prefixing the alternative that reaches it gives a derivation in the new grammar.
Show every generated string lies in the union
Why: A derivation's first step picks one alternative. Afterwards only that grammar's variables appear, so the rest of the derivation lies entirely in that grammar.
Note where disjointness was used
Why: Exactly in the previous step. Shared variables would let a derivation begun in one grammar be continued by the other's rules.
Verify on a concrete pair
Why: Taking the matched-counts language and the double-b-counts language, the combined grammar derives aabb through the first branch and abb through the second, and derives abbb through neither — matching the union exactly.
\[ L(G) = L_1 \cup L_2 \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Prove closure under union", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: Taking the matched-counts language and the double-b-counts language, the combined grammar derives aabb through the first branch and abb through the second, and derives abbb through neither — matching the union exactly.
Concept
Even simpler: one rule sending a fresh start variable to the two old start variables in sequence.
\[ S \to S_1 S_2 \]
A derivation from this rule splits into an independent derivation from each old start variable, and the yields concatenate in order. Since the variable sets are disjoint, neither derivation can interfere with the other.
Compare Lesson 7, where the machine construction needed ε-arrows and a careful demotion of the first machine's accepting states. Here the same content is one rule with no side conditions.
Step zero
Discussion prompt
Prove closure under concatenation — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.
Hint: It starts with: Build the grammar
Answer:
Worked example
Both inclusions, and a note on why the grammar side is so much easier.
Build the grammar
Why: Rename apart, union the rules, add the single joining rule.
\[ S \to S_1 S_2 \]
Show every concatenation is generated
Why: Take a string of the first language and one of the second, with their derivations. Apply the joining rule, then run both derivations independently on the two variables.
Show every generated string is a concatenation
Why: The only rule for the fresh start variable produces the two old ones. Everything derived from the first lies in the first language and likewise for the second, so the yield splits accordingly.
Compare with the machine construction
Why: Lesson 7's machine version had to guess where the split fell. Here the split is recorded structurally by the two subtrees, so no guessing appears in the proof at all.
Verify the split is recoverable from the parse tree
Why: The root's two children yield the two halves, so a parse tree exhibits the split explicitly. That is the concrete sense in which a grammar carries structure the machine had to search for.
\[ L(G) = L_1 L_2 \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Prove closure under concatenation", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: The root's two children yield the two halves, so a parse tree exhibits the split explicitly. That is the concrete sense in which a grammar carries structure the machine had to search for.
Concept
Replacing each terminal by a fixed string is closed too, and the construction is a substitution on the grammar.
\[ h : \Sigma \to \Gamma^{*} \]
Replace every occurrence of every terminal in every right-hand side by that terminal's image. Variables are untouched, and the rule structure is unchanged.
\[ A \to aBb \;\Longrightarrow\; A \to h(a)\,B\,h(b) \]
A parse tree in the new grammar has the same shape as the old one, with each leaf expanded into a short string. So the yields correspond exactly, and no strings are gained or lost.
Estimation
Predict first
The substitution, and a check that nothing subtle happens at the leaves.
Commit before you compute: what does Prove closure under homomorphism come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.
Correct: Verify on a concrete map
Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. Sending a to the two-symbol block and b to the empty string turns the matched-counts grammar into one generating runs of that block.
Worked example
The substitution, and a check that nothing subtle happens at the leaves.
Apply the substitution
Why: Rewrite every right-hand side, replacing each terminal by its image and leaving each variable alone.
Check the rule shapes stay legal
Why: A right-hand side may grow longer, and a terminal mapped to the empty string simply disappears. Both results are legal right-hand sides, so no repair is needed.
Match the trees
Why: The new tree has the same internal structure; only the leaves differ, each carrying a string rather than a symbol.
Read off the yields
Why: Concatenating the expanded leaves left to right gives exactly the homomorphic image of the original yield.
\[ \mathrm{yield}(T') = h\big(\mathrm{yield}(T)\big) \]
Verify on a concrete map
Why: Sending a to the two-symbol block and b to the empty string turns the matched-counts grammar into one generating runs of that block. Deriving the two-copy string confirms the image is as predicted, and no string outside the image appears.
\[ h(a) = 01, \; h(b) = \varepsilon \;\Rightarrow\; h(L) = (01)^{*} \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Prove closure under homomorphism", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: A right-hand side may grow longer, and a terminal mapped to the empty string simply disappears. Both results are legal right-hand sides, so no repair is needed.
Concept
One self-recursive rule, with an empty alternative for the zero-copies case.
\[ S \to S_1 S \;\mid\; \varepsilon \]
Each application of the recursive alternative contributes one member of the language, and the empty alternative ends the sequence. So the yield is any finite sequence of members joined together.
The empty string comes from taking the empty alternative immediately, which is required since the star of any language contains it. That is the same boundary case Lesson 7's machine construction needed a fresh state for.
\[ \varepsilon \in L_1^{*} \quad\text{always} \]
Missing information
Discussion prompt
The construction, and the boundary case that the machine version found awkward.
What do you need to know — or decide — before the first line can be written? List everything the problem has to hand you.
Hint: Anything you would have to invent to get started is a thing the problem must supply.
Answer:
Rename apart, keep the original rules, and add the fresh start variable with its two alternatives.
Worked example
The construction, and the boundary case that the machine version found awkward.
Build the grammar
Why: Rename apart, keep the original rules, and add the fresh start variable with its two alternatives.
Show every finite sequence of members is generated
Why: Apply the recursive alternative once per member, then the empty alternative. Each occurrence of the old start variable derives its own member.
\[ S \Longrightarrow^{*} S_1^{k} \Longrightarrow^{*} x_1x_2\cdots x_k \]
Show every generated string is such a sequence
Why: Each use of the recursive alternative contributes exactly one subtree rooted at the old start variable, whose yield lies in the language. The derivation ends with the empty alternative.
Check the boundary case
Why: Zero applications gives the empty string, which must be in the star and is. This is where Lesson 7's naive machine construction went wrong, and the grammar version has no analogous trap.
Verify the fresh start variable was necessary
Why: Adding the alternatives to the old start variable instead would let a member's own derivation be interrupted by the recursion, generating strings that are not sequences of members. The fresh variable keeps the two roles separate — the grammar-side echo of Lesson 7's inert start state.
\[ L(G) = L_1^{*} \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Prove closure under star", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: Zero applications gives the empty string, which must be in the star and is. This is where Lesson 7's naive machine construction went wrong, and the grammar version has no analogous trap.
Intuition
All three constructions are one rule, and the reason is structural rather than lucky.
Union, concatenation and star are exactly the three ways of building a string from smaller pieces: choose one of two, join two in order, or repeat. A grammar rule is precisely a statement of how a string is built from pieces.
So the three operations map onto the three shapes a right-hand side can take. The match is exact, which is why Lesson 13's design recipe already used all three without calling them closure properties.
\[ \text{alternatives} \;\leftrightarrow\; \text{union}, \quad \text{sequence} \;\leftrightarrow\; \text{concatenation}, \quad \text{recursion} \;\leftrightarrow\; \text{star} \]
Prediction
Predict first
In the union construction, what goes wrong if the two grammars share a variable name?
Answer it in your own words, now, with nothing to choose from. The options are on the next slide — and picking the right one off a list is an easier skill than producing it.
Correct: A derivation begun in one grammar could be continued by the other's rules
Why: The second inclusion relies on a derivation staying inside whichever grammar it started in. A shared variable gives rules from both grammars, so a derivation could mix them and produce a string in neither language.
Check
Recall why the variable sets must be disjoint.
Check your understanding
In the union construction, what goes wrong if the two grammars share a variable name?
Answer: A
Why: The second inclusion relies on a derivation staying inside whichever grammar it started in. A shared variable gives rules from both grammars, so a derivation could mix them and produce a string in neither language.
Section
Section 3
Concept
The regular languages were closed under intersection by the product construction. Here the property is false, and refuting it takes a counterexample.
A counterexample means two languages, each demonstrably context-free, whose intersection is demonstrably not. Both halves need proof.
\[ L_1, L_2 \in \mathcal{CF} \quad\text{but}\quad L_1 \cap L_2 \notin \mathcal{CF} \]
Lesson 18 supplied the second half: the three-matched-counts language is outside the class. The task is to write it as an intersection of two languages inside the class.
Fill the middle
Fill in the blanks
From Exhibit the counterexample — finish the line. Write what belongs on the right of the equals sign before you look.
L_1 \cap L_2 = \{\, a^{n}b^{n}c^{n} \,\}
Why: Producing the right-hand side unprompted is the difference between recognising this line and being able to use it. It matches a's against b's and lets the c's run free.
Worked example
Two languages, each pairing one thing, whose intersection pairs two.
\[ L_1 = \{a^{n}b^{n}c^{m}\}, \qquad L_2 = \{a^{m}b^{n}c^{n}\} \]
Show the first is context-free
Why: It matches a's against b's and lets the c's run free. A grammar joins a matched-counts variable with a free-c variable.
\[ S \to A C, \quad A \to aAb \;\mid\; \varepsilon, \quad C \to cC \;\mid\; \varepsilon \]
Show the second is context-free
Why: Symmetrically, it matches b's against c's and lets the a's run free.
\[ S \to A B, \quad A \to aA \;\mid\; \varepsilon, \quad B \to bBc \;\mid\; \varepsilon \]
Compute the intersection
Why: A string in both has its a's matching its b's and its b's matching its c's, so all three counts agree — and the symbols are in order.
\[ L_1 \cap L_2 = \{\, a^{n}b^{n}c^{n} \,\} \]
Invoke Lesson 18
Why: That language was proved beyond the class by the pumping lemma, using the block-and-window argument.
Verify both inclusions of the intersection equality
Why: Any string in both languages has the ordered form with the a count equal to the b count and the b count equal to the c count, hence all three equal. Conversely any string with all three equal and in order lies in both. So the identification is exact and the counterexample stands.
\[ L_1 \cap L_2 \notin \mathcal{CF} \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Exhibit the counterexample", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: Any string in both languages has the ordered form with the a count equal to the b count and the b count equal to the c count, hence all three equal. Conversely any string with all three equal and in order lies in both. So the identification is exact and the counterexample stands.
Step zero
Discussion prompt
Build a second counterexample — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.
Hint: It starts with: Choose a different known non-context-free language
Answer:
Worked example
One counterexample settles the question, but building a second confirms the shape is general rather than a special case.
Choose a different known non-context-free language
Why: Take the repeated-block language, which Lesson 18 placed outside the class.
\[ \{\, ww : w \in \{a,b\}^{*} \,\} \]
Look for two context-free languages intersecting to it
Why: Split the requirement into two halves, each of which needs only one pairing. One language checks that the first and third quarters match; the other checks the second and fourth.
Note each half is achievable with one stack
Why: Matching one pair of blocks separated by others is exactly the shape Lesson 16 handled with a single push-and-pop phase.
Take the intersection
Why: A string satisfying both halves has all four quarters aligned, which makes it a block written twice.
Verify the pattern matches the first counterexample
Why: Both examples split a two-pairing requirement into two one-pairing languages. That is the general recipe, and it works whenever a known non-context-free language demands exactly two independent pairings.
\[ \text{two pairings} = \text{one pairing} \cap \text{one pairing} \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Build a second counterexample", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: Both examples split a two-pairing requirement into two one-pairing languages. That is the general recipe, and it works whenever a known non-context-free language demands exactly two independent pairings.
Intuition
The construction is not arbitrary. It follows directly from what a stack can and cannot do.
Each language demands one pairing, which one stack handles. The intersection demands both pairings at once, which would need two stacks — and Lesson 18 proved no single-stack machine suffices.
So the counterexample is really the two-stack observation from Section 1, made concrete. Any pair of languages each pairing a different thing, sharing a middle block, would do equally well.
\[ \text{one pairing each} \;+\; \text{one pairing each} \;=\; \text{two pairings} \]
Anomaly
Predict first
A student writes this, and it looks reasonable:
The class is closed under union. What about intersection?
It is wrong. Say what breaks — and say it before you turn the page.
Correct: Intersection is expressible using union and complement, and union is closed, so intersection should be closed too.
The class is closed under union. What about intersection?
Why: Intersection is expressible using union and complement, and union is closed, so intersection should be closed too.
Trap
The class is closed under union. What about intersection?
Argue from De Morgan
Why: Intersection is expressible using union and complement, and union is closed, so intersection should be closed too.
\[ L_1 \cap L_2 = \overline{\overline{L_1} \cup \overline{L_2}} \]
Declare the property proved
Why: Since the right-hand side uses only union and complement, and union is closed, the intersection must be context-free.
The class is closed under union. What about intersection?
Check every operation the identity uses
Why: The identity uses complement as well as union. Deriving closure under intersection from it requires closure under complement, which has not been established.
\[ \text{De Morgan needs} \;\cup\; \text{and} \;\overline{\;\;} \]
Note the direction the argument really runs
Why: Since intersection is not closed and union is, the identity shows complement cannot be closed either. The De Morgan identity is a tool for propagating a failure, not for manufacturing a success.
\[ \cup \text{ closed}, \; \cap \text{ not closed} \;\Rightarrow\; \overline{\;\;} \text{ not closed} \ \checkmark \]
Notation
Annotate
From Trap: assuming intersection is closed because union is — read this one piece at a time. What is each part doing?
On: \( L_1 \cap L_2 = \overline{\overline{L_1} \cup \overline{L_2}} \)
Check
Think about how many pairings each language demands.
Check your understanding
Why is each of the two languages in the counterexample context-free while their intersection is not?
Answer: A
Why: One stack can push a count and pop it once. The first language pairs a's with b's and the second pairs b's with c's; satisfying both requires the b count to be checked twice, which one stack cannot do.
Section
Section 4
Concept
No new counterexample is needed. The failure of complement follows from the failure of intersection, by the identity the trap misused.
Suppose the class were closed under complement. Since it is closed under union, De Morgan would then give closure under intersection — which Section 3 refuted.
\[ \overline{\;\;} \text{ closed} \;+\; \cup \text{ closed} \;\Rightarrow\; \cap \text{ closed} \]
So the assumption is false: the context-free languages are not closed under complement. The argument is three lines and needs no new language.
Estimation
Predict first
The derivation in full, and a note on what it does and does not tell you.
Commit before you compute: what does Prove complement fails come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.
Correct: Verify what has and has not been shown
Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. This proves some context-free language has a non-context-free complement, without identifying one.
Worked example
The derivation in full, and a note on what it does and does not tell you.
Assume closure under complement, for contradiction
Why: Suppose the complement of every context-free language were context-free.
Take the two languages from Section 3
Why: Both are context-free, and their intersection is not.
Apply De Morgan
Why: Their intersection equals the complement of the union of their complements. Under the assumption, each complement is context-free; union is closed; and the outer complement is closed by the assumption again.
\[ L_1 \cap L_2 = \overline{\overline{L_1} \cup \overline{L_2}} \]
Read the contradiction
Why: The right-hand side would be context-free, but the left-hand side was proved not to be. So the assumption fails.
Verify what has and has not been shown
Why: This proves some context-free language has a non-context-free complement, without identifying one. It is a non-constructive argument of exactly the kind Lesson 12 discussed, and a specific witness needs separate work.
\[ \exists L \in \mathcal{CF} : \overline{L} \notin \mathcal{CF} \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Prove complement fails", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: This proves some context-free language has a non-context-free complement, without identifying one. It is a non-constructive argument of exactly the kind Lesson 12 discussed, and a specific witness needs separate work.
Concept
Lesson 16 noted that deterministic pushdown automata are closed under complement. That contrast is worth holding beside this section's failure.
| Deterministic | General | |
|---|---|---|
| complement | closed | not closed |
| union | not closed | closed |
| intersection | not closed | not closed |
The deterministic subclass trades union for complement: one computation per input makes negation easy and makes combining two machines hard. The general class makes the opposite trade, and neither is closed under intersection.
Pattern
Step through it
Step through The deterministic subclass behaves differently one row at a time. What is driving the change, and what would the row after the last one be?
Ranking
Put in order
Put the moves of Show the deterministic class is not closed under union into the order they have to happen.
Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. Swapping accepting states works because each input has exactly one computation.
Worked example
Complete the contrast, using the closure facts already available.
Recall the deterministic class is closed under complement
Why: Swapping accepting states works because each input has exactly one computation.
Suppose it were also closed under union
Why: Then by De Morgan it would be closed under intersection as well.
\[ \overline{\;\;} \text{ and } \cup \text{ closed} \;\Rightarrow\; \cap \text{ closed} \]
Derive the contradiction
Why: The two languages from Section 3 are each deterministic — each needs one pairing with the phase boundary visible in the input — and their intersection is not even context-free, let alone deterministic.
Conclude
Why: The deterministic class is not closed under union, despite the general class being closed under it.
Verify the trade-off is symmetric
Why: The general class has union and lacks complement; the deterministic class has complement and lacks union. Both lack intersection, and in both cases De Morgan propagates one failure to the other — the same argument run in opposite directions.
\[ \text{deterministic: } \overline{\;\;} \text{ yes}, \cup \text{ no} \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Show the deterministic class is not closed under union", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: The general class has union and lacks complement; the deterministic class has complement and lacks union. Both lack intersection, and in both cases De Morgan propagates one failure to the other — the same argument run in opposite directions.
Concept
The derivation gives existence without an example. One is worth knowing, since Lesson 16 used it.
The complement of the repeated-block language is context-free, while the repeated-block language itself is not — as Lesson 18 proved.
\[ \overline{\{ww\}} \in \mathcal{CF}, \qquad \{ww\} \notin \mathcal{CF} \]
So here the complement is the easy one. A string fails to be a block written twice when it has odd length, or when its two halves differ at some position — and a machine can guess that position and check it, which is exactly one pairing.
Missing information
Discussion prompt
Sketch the grammar for the complement, which explains the asymmetry.
What do you need to know — or decide — before the first line can be written? List everything the problem has to hand you.
Hint: Anything you would have to invent to get started is a thing the problem must supply.
Answer:
A string is not a block written twice when its length is odd, or when its length is even and the halves differ somewhere.
Worked example
Sketch the grammar for the complement, which explains the asymmetry.
Split into two cases
Why: A string is not a block written twice when its length is odd, or when its length is even and the halves differ somewhere.
Handle the odd case
Why: Odd-length strings form a regular language, hence context-free, generated by a simple right-linear grammar.
Handle the differing case
Why: If the halves differ, there is a position where one has an a and the other a b. A machine can guess that position, push its distance from the centre, and check the corresponding symbol.
Note that only one pairing is needed
Why: Only the two mismatched positions must be related, so one stack suffices. Checking that every position matches would need unboundedly many pairings, which is why the original language is beyond the class.
\[ \text{one mismatch} \;\text{ versus }\; \text{all positions match} \]
Verify the asymmetry is genuine
Why: Finding one witness of failure is an existential and needs one guess; verifying success is a universal and needs many checks. Nondeterminism makes existentials cheap and universals expensive — the same asymmetry Lesson 5 identified for finite automata.
\[ \exists \text{ a mismatch} \;\text{ is cheap}; \quad \forall \text{ positions match} \;\text{ is not} \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "See why the complement is the easier language", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: Finding one witness of failure is an existential and needs one guess; verifying success is a universal and needs many checks. Nondeterminism makes existentials cheap and universals expensive — the same asymmetry Lesson 5 identified for finite automata.
Intuition
Union succeeded and intersection failed, and complement inherited the failure. There is one reason underneath all three.
A nondeterministic machine accepts when some computation succeeds. Union is an existential over two machines, so it composes with that. Intersection is a universal — both must succeed — and nondeterminism does not provide universals.
\[ \cup \;\leftrightarrow\; \exists, \qquad \cap \;\leftrightarrow\; \forall \]
Complement turns an existential into a universal, so it fails for the same reason. The regular class escaped only because determinization was available there, and Lesson 16 showed it is not available here.
Commit first
Predict first
What does the failure of complement follow from?
Commit to an answer, then rate it — certain, fairly sure, or guessing — and write the rating down before you turn the page.
Correct: Closure under union, together with the failure of intersection
Why: If complement were closed, De Morgan would combine it with the established closure under union to give closure under intersection — which Section 3 refuted. So complement cannot be closed.
The rating matters as much as the answer: confident-and-wrong is the combination that survives revision, because nothing about it feels like it needs revisiting.
Check
Recall which properties the derivation combines.
Check your understanding
What does the failure of complement follow from?
Answer: A
Why: If complement were closed, De Morgan would combine it with the established closure under union to give closure under intersection — which Section 3 refuted. So complement cannot be closed.
Section
Section 5
Concept
General intersection fails, but a restricted version holds — and it is the single most useful closure property of this class.
closure under regular intersection — The intersection of a context-free language with a regular language is context-free.
\[ L \in \mathcal{CF}, \; R \text{ regular} \;\Longrightarrow\; L \cap R \in \mathcal{CF} \]
Every closure argument in Lessons 18 and 19 relies on this. It is what makes 'intersect with a simple pattern' a legitimate move.
Intuition
The obstruction in Section 1 was that a product of two pushdown automata would need two stacks. Here only one machine has a stack.
A finite automaton's whole situation is a single state, so pairing it with a pushdown automaton's situation gives a state pair plus one stack. That is still a pushdown automaton.
\[ (Q_P \times Q_D) \text{ states}, \quad \text{one stack} \]
So the product construction returns, in a form that respects the stack budget. The asymmetry between the two operands is exactly what makes it work.
Step zero
Discussion prompt
Prove closure under regular intersection — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.
Hint: It starts with: Take the two machines
Answer:
Worked example
The construction and both inclusions.
Take the two machines
Why: A pushdown automaton for the context-free language and a deterministic finite automaton for the regular one.
Build the product
Why: States are pairs. On each input symbol, the first component moves as the pushdown automaton would and the second as the finite automaton would, in lockstep.
\[ \delta\big((p,q), a, X\big) = \{\,((p',q'), \gamma) : (p',\gamma) \in \delta_P(p,a,X), \; q' = \delta_D(q,a) \,\} \]
Handle the free moves
Why: On a move consuming no input, the first component moves and the second stays put — the finite automaton must not advance without reading a symbol.
\[ \delta\big((p,q), \varepsilon, X\big) : \; q' = q \]
Choose the accepting pairs
Why: Accept when both components accept, which is the intersection condition.
\[ F = F_P \times F_D \]
Verify both inclusions and the stack budget
Why: A string accepted by the product has an accepting computation in each component, so it lies in both languages; conversely, accepting computations in each can be run in lockstep. And the product has exactly one stack — the pushdown component's — so it is a legitimate pushdown automaton.
\[ L(P') = L(P) \cap L(D) \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Prove closure under regular intersection", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: A string accepted by the product has an accepting computation in each component, so it lies in both languages; conversely, accepting computations in each can be run in lockstep. And the product has exactly one stack — the pushdown component's — so it is a legitimate pushdown automaton.
Anomaly
Predict first
A student writes this, and it looks reasonable:
Build the product of a pushdown automaton and a finite automaton.
It is wrong. Say what breaks — and say it before you turn the page.
Correct: Treat the two machines symmetrically: whenever the product takes a move, step both components.
Build the product of a pushdown automaton and a finite automaton.
Why: Treat the two machines symmetrically: whenever the product takes a move, step both components.
Trap
Build the product of a pushdown automaton and a finite automaton.
Advance both components on every move
Why: Treat the two machines symmetrically: whenever the product takes a move, step both components.
\[ \delta\big((p,q),\varepsilon,X\big) : \; q' = \delta_D(q, ?) \]
Notice there is no symbol to advance on
Why: A free move consumes no input, so the finite automaton has nothing to read. Advancing it would require inventing a symbol, and the machine would drift out of step with the input.
Build the product of a pushdown automaton and a finite automaton.
Advance the finite component only on input-consuming moves
Why: The finite automaton's state must always reflect exactly the input read so far, so a move that reads nothing must leave it unchanged.
\[ \delta\big((p,q),\varepsilon,X\big) : \; q' = q \]
Confirm the invariant
Why: After any computation, the second component is the state the finite automaton would be in after reading the consumed input. That is what makes the accepting condition mean what it should.
\[ q = \hat{\delta}_D(q_0, \text{consumed input}) \ \checkmark \]
Two truths and a lie
Sort into buckets
Some of these hold up and some are the exact mistakes this lesson is built to prevent. Sort them.
Worked example
Apply it the way Lesson 18 did, on a fresh language.
Take a candidate
Why: The strings over three symbols in which the counts of a, b and c are all equal, in any order.
Assume it is context-free
Why: For contradiction, suppose some grammar generates it.
Intersect with a regular pattern
Why: Take the ordered strings: any a's, then any b's, then any c's. A four-state machine recognizes it, so it is regular.
\[ R = a^{*}b^{*}c^{*} \]
Apply the closure property
Why: The intersection of a context-free language with a regular one is context-free. But the intersection is the three-matched-counts language, which is not.
Verify the intersection equality and conclude
Why: A string with all counts equal and in order has the matched form; a matched string has all counts equal and is in order. Both inclusions hold, so the contradiction stands and the candidate is not context-free.
\[ L \cap R = \{a^{n}b^{n}c^{n}\} \;\Rightarrow\; L \notin \mathcal{CF} \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Use the property in a classification argument", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: A string with all counts equal and in order has the matched form; a matched string has all counts equal and is in order. Both inclusions hold, so the contradiction stands and the candidate is not context-free.
Hypothesis
Predict first
Use regular intersection to simplify a language is about to be worked. State your hypothesis first: which rule or definition decides this one, and what is the first move it forces? Then watch whether the example agrees with you.
Correct: Take a context-free language
Why: The balanced-bracket strings over one bracket kind.
A hypothesis you wrote down is falsifiable; a vague sense of how it will go is not. If the example opens somewhere else, that gap is the thing worth chasing.
Worked example
The property is not only a proof device — it also builds languages, by carving a context-free language down with a pattern.
Take a context-free language
Why: The balanced-bracket strings over one bracket kind.
Intersect with a regular constraint
Why: Keep only those of length at most six — a finite, hence regular, condition.
\[ R = \{w : |w| \le 6\} \]
Apply the closure property
Why: The result is context-free. In fact it is finite, hence regular, but the closure property is what licenses the first conclusion without inspecting the result.
Try a more interesting constraint
Why: Instead keep only the strings whose length is a multiple of four. That is regular, and the intersection is an infinite context-free language.
Verify the construction on a member and a non-member
Why: The four-symbol nested string is balanced and has length four, so it survives both constraints. The two-symbol pair is balanced but has length two, so the intersection excludes it — exactly as the product machine would.
\[ (()) \in L \cap R, \qquad () \notin L \cap R \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Use regular intersection to simplify a language", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: The four-symbol nested string is balanced and has length four, so it survives both constraints. The two-symbol pair is balanced but has length two, so the intersection excludes it — exactly as the product machine would.
Intuition
Regular intersection has a practical face worth naming, beyond its role in proofs.
A syntax is described by a grammar, and additional constraints — token patterns, lexical rules, layout requirements — are usually regular. Intersecting the two is exactly what a lexer-plus-parser pipeline computes.
The closure property is the guarantee that this composition stays within the class the parser can handle. Were it not closed, adding a regular constraint could push a language beyond any parser.
\[ \text{grammar} \;\cap\; \text{lexical constraints} \;=\; \text{still context-free} \]
Constraint
Discussion prompt
Run The closure-argument recipe for this class with this step confiscated:
Choose a helper that is regular, not merely context-free.
Is it still possible? If it is, say what takes its place and what it costs you. If it is not, say exactly what that step was providing that nothing else does.
Hint: A step you can drop for free was never load-bearing. If you cannot drop it, name the thing that goes wrong the moment it is gone.
Answer:
Pattern
The same five steps as Lesson 7, with one substitution that matters.
Step three is the substitution. Using a context-free helper licenses nothing, because general intersection is not closed — the error the trap in Lesson 18 warned about.
Edge cases
Discussion prompt
The closure-argument recipe for this class works on the cases you have just seen. Push it to the edge: what is the most degenerate input it still handles — empty, zero, one item, everything equal — and what is the first case where it stops being true? Name the case, not just "it breaks".
Hint: Try the smallest legal input, then the largest, then the one where two things collide. Methods are specified at their edges; the middle takes care of itself.
Answer:
The same five steps as Lesson 7, with one substitution that matters.
Prediction
Predict first
Why does the product construction work when one operand is regular?
Answer it in your own words, now, with nothing to choose from. The options are on the next slide — and picking the right one off a list is an easier skill than producing it.
Correct: The finite automaton contributes only a state, so the product still has just one stack
Why: A product must track both machines' situations at once. A finite automaton's situation is a single state, so pairing it with a pushdown automaton's situation gives state pairs plus the one existing stack — still within the model.
Check
Think about what each component contributes to the product.
Check your understanding
Why does the product construction work when one operand is regular?
Answer: A
Why: A product must track both machines' situations at once. A finite automaton's situation is a single state, so pairing it with a pushdown automaton's situation gives state pairs plus the one existing stack — still within the model.
Section
Section 6
Concept
Everything proved in this lesson, beside the corresponding row from Lesson 7.
| Operation | Regular | Context-free |
|---|---|---|
| union | yes | yes |
| concatenation | yes | yes |
| Kleene star | yes | yes |
| intersection | yes | no |
| complement | yes | no |
| difference | yes | no |
| intersection with a regular language | yes | yes |
| reversal | yes | yes |
| homomorphism | yes | yes |
The three no rows are what distinguish the classes, and they are the rows that get used as proof techniques.
Estimation
Predict first
One of the remaining yes rows, since the construction is instructive.
Commit before you compute: what does Prove closure under reversal come out to? A rough magnitude and the right form is enough — the point is to have something concrete to be wrong about.
Correct: Verify on a concrete grammar
Why: A prediction you can defend turns the computation into a check rather than a leap of faith — and an answer that contradicts it is caught on the spot. Reversing the matched-counts grammar turns its recursive rule into one producing a b before and an a after, generating b's followed by a's in matching numbers — exactly the reversal of the original language.
Worked example
One of the remaining yes rows, since the construction is instructive.
Take a grammar for the language
Why: Any grammar will do; no normal form is needed.
Reverse every right-hand side
Why: Leave the variables and the start variable alone, and reverse the order of symbols in each rule's right-hand side.
\[ A \to \alpha \;\Longrightarrow\; A \to \alpha^{R} \]
See why the yields reverse
Why: A parse tree in the new grammar is the old tree with every node's children in reverse order. Reading its leaves left to right gives the old yield backwards.
Check the correspondence is a bijection
Why: Reversing right-hand sides twice returns the original grammar, so the trees correspond one to one and no strings are gained or lost.
Verify on a concrete grammar
Why: Reversing the matched-counts grammar turns its recursive rule into one producing a b before and an a after, generating b's followed by a's in matching numbers — exactly the reversal of the original language.
\[ L^{R} = \{b^{n}a^{n}\} \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Prove closure under reversal", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: Reversing right-hand sides twice returns the original grammar, so the trees correspond one to one and no strings are gained or lost.
Concept
Reversal is closed and the repeated-block language is outside the class. Those two facts look in tension and are not.
Reversal transforms a language into another language, and the construction reverses every rule. Repetition is a condition relating two parts of one string, which is a different kind of demand entirely.
\[ L^{R} \;: \text{ an operation} \qquad \{ww\} \;: \text{ a condition} \]
So closure under reversal says nothing about whether a machine can check that two halves are equal. The first is about rewriting a description; the second is about what a single computation can verify.
Step zero
Discussion prompt
Distinguish an operation from a condition — before any calculation: what is the plan? Name the moves in order, in plain English, without doing the arithmetic.
Hint: It starts with: Take a context-free language and reverse it
Answer:
Worked example
Practise the distinction, since conflating the two produces confident wrong answers.
Take a context-free language and reverse it
Why: The matched-counts language reverses to b's followed by a's in matching numbers, and reversing its grammar produces one for exactly that.
\[ L^{R} = \{b^{n}a^{n}\} \in \mathcal{CF} \]
Now take the language of strings equal to their own reversal
Why: That is the palindromes — a condition, not an operation. It happens to be context-free, but for an unrelated reason: a stack returns symbols reversed.
Take the language of strings equal to their own repetition
Why: That is the repeated-block language, and Lesson 18 placed it outside the class.
Note the pattern
Why: Both palindromes and repeated blocks are conditions comparing two halves. One is within reach because the comparison is reversed; the other is not because it is in the same order.
Verify that closure under reversal did not help either way
Why: Reversal being closed tells you the image of a language under reversal stays in the class. It says nothing about languages defined by a self-referential condition, which is why both classifications had to be established separately.
\[ \text{closure under } {}^{R} \;\not\Rightarrow\; \{ww^{R}\} \text{ or } \{ww\} \text{ classified} \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Distinguish an operation from a condition", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: Reversal being closed tells you the image of a language under reversal stays in the class. It says nothing about languages defined by a self-referential condition, which is why both classifications had to be established separately.
Concept
Difference fails in general, since it would give complement by subtracting from everything. But one restricted form holds.
Subtracting a regular language from a context-free one is closed, because the complement of a regular language is regular and regular intersection is closed.
\[ L \setminus R = L \cap \overline{R}, \qquad \overline{R} \text{ regular} \]
Subtracting a context-free language from a regular one is not closed, and neither is the general case. The asymmetry is the same one as for intersection.
Explain it
Discussion prompt
Explain Difference, and the special case that survives to a student a year behind you. No notation, no jargon they have not met — and it still has to be true.
Hint: If your explanation needs a symbol they have never seen, you are describing the notation rather than the idea.
Answer:
Difference fails in general, since it would give complement by subtracting from everything. But one restricted form holds.
Ranking
Put in order
Put the moves of Classify a language using the table into the order they have to happen.
Why: These are the moves of the worked example in the order it makes them, and each one is set up by the one before it. The strings that are a matched-counts string, followed by any number of c's, with the whole thing of even length.
Worked example
Use the closure properties as a fast classification tool, rather than proving from scratch.
Take a language built from familiar pieces
Why: The strings that are a matched-counts string, followed by any number of c's, with the whole thing of even length.
Identify the pieces and the operations
Why: A matched-counts language concatenated with a run of c's, then intersected with the even-length language.
\[ \big(\{a^{n}b^{n}\} \cdot c^{*}\big) \;\cap\; \{w : |w| \text{ even}\} \]
Check each piece and operation against the table
Why: The first factor is context-free; the second is regular hence context-free; concatenation is closed. The even-length language is regular, and intersection with a regular language is closed.
Conclude
Why: Every operation used is one the class is closed under, and every piece is in the class, so the whole language is context-free.
Verify no forbidden operation was used
Why: The only intersection was with a regular language, which is the permitted form. Had the second operand been context-free instead, the argument would have proved nothing — and the language might well have been outside the class.
\[ \text{all operations closed} \;\Rightarrow\; \text{context-free} \ \checkmark \]
Picture it
Animation
Shows: Each line of the worked example "Classify a language using the table", appearing one at a time.
The same working the example does, in the order a tutor would write it.
Takeaway: The first factor is context-free; the second is regular hence context-free; concatenation is closed. The even-length language is regular, and intersection with a regular language is closed.
Intuition
The table is not only a reference. The differences between its columns identify which class a language belongs to.
Each of these turns a closure fact into a modelling heuristic, applicable before any proof is attempted.
Analogy
Discussion prompt
Explain Reading the table as a diagnostic by analogy to something with no Theory of Computation in it at all — a queue, a recipe, a map, a bank balance, whatever fits. Then say where your analogy breaks.
Hint: An analogy that never breaks is not an analogy, it is the same idea wearing a hat. Find the seam — that is the part that is actually new.
Answer:
The table is not only a reference. The differences between its columns identify which class a language belongs to.
Elimination
Eliminate the wrong options
You know L is context-free and R is regular. Which of these is guaranteed context-free?
3 of these 4 are wrong. Strike them one at a time, and say what rules each one out before you strike the next. The survivor is the answer.
Survives elimination: A
Why: Subtracting a regular language is intersecting with its complement, and the complement of a regular language is regular. Intersection with a regular language is closed, so the result is context-free.
Check
Check which operations the construction uses.
Check your understanding
You know L is context-free and R is regular. Which of these is guaranteed context-free?
Answer: A
Why: Subtracting a regular language is intersecting with its complement, and the complement of a regular language is regular. Intersection with a regular language is closed, so the result is context-free.
Concept
A closure property says the result stays in the class. It does not say anything can be computed about it, and the distinction matters from Lesson 24 onward.
| Question | About | Answered by |
|---|---|---|
| is the union context-free? | closure | yes, this lesson |
| is a given string in the union? | decidability | yes, by parsing |
| is the union empty? | decidability | yes, Lesson 24 |
| do two grammars generate the same language? | decidability | no, Lesson 29 |
The last row is the surprise. Closure gives constructions, and constructions give objects — but having an object does not mean every question about it can be answered.
Discrimination
Sort into buckets
Sort these by About, from memory, without looking back at Closure and decidability are different questions. Telling them apart on the spot is the skill; the table is only where the answer happens to be written down.
Intuition
Two rows of the table are now filled in. It is worth guessing what the third will look like before Lesson 20 arrives.
The pattern so far: more powerful models lose closure properties as their acceptance conditions become harder to negate. The regular class had determinization and kept everything; this class lost complement and intersection.
The machines of Lesson 20 recover intersection and complement in one sense and lose them in another — the languages they decide are closed under both, while the languages they merely recognize are not. That split is the subject of Lessons 24 to 26, and it is the most consequential distinction remaining in the course.
\[ \text{decidable: closed} \qquad \text{recognizable: not closed under complement} \]
Counterexample
Discussion prompt
Two rows of the table are now filled in. It is worth guessing what the third will look like before Lesson 20 arrives.
That is stated as though it always holds. Do one of two things: produce a case where it fails, or say precisely what rules such a case out. "It just does" is not on the menu.
Hint: Hunt at the extremes first — zero, one, negative, empty, equal. If every extreme survives, the reason they survive is the proof.
Concept
Seven lessons have now given the context-free languages the same treatment the regular languages received in Lessons 4 to 12.
| Question | Answered in |
|---|---|
| how are they described? | Lessons 13 and 14 — grammars and ambiguity |
| is there a normal form? | Lesson 15 |
| what machine recognizes them? | Lesson 16 |
| are the two descriptions equivalent? | Lesson 17 |
| how do you prove a language is outside? | Lesson 18 |
| which operations stay inside? | this lesson |
The same six questions were answered for the regular class, and they will be asked once more — with very different answers — of the machines introduced next.
Comparison
Comparison matrix
From What this chapter established: refill the Answered in column from what you know. The rest of the table is as it appeared.
| Question | Answered in |
|---|---|
| how are they described? | Lessons 13 and 14 — grammars and ambiguity |
| is there a normal form? | Lesson 15 |
| what machine recognizes them? | Lesson 16 |
| are the two descriptions equivalent? | Lesson 17 |
| how do you prove a language is outside? | Lesson 18 |
| which operations stay inside? | this lesson |
Ranking
Put in order
These are the steps of Choosing a formalism for a closure proof, scrambled. Put them back in order before the next slide shows you.
Why: This is the order the recipe itself gives. Recalling the sequence without the slide in front of you is the difference between recognising the method and being able to run it — most of what goes wrong in practice is a step done out of turn.
Pattern
Collected, since the choice is what makes these proofs short or long.
The last line is worth taking literally. Every proof in this lesson that ran to more than a few steps was on the machine side, and every one-line proof was on the grammar side.
Real world
Discussion prompt
Outside this lesson: where does Context-Free Closure Properties actually turn up? Name one concrete situation — a job, a piece of software someone ships, a decision somebody has to make — and say which part of Choosing a formalism for a closure proof is doing the work in it.
Hint: Vague is the failure mode here. "Engineering" is not a situation; "deciding whether this build is fast enough to ship" is.
Answer:
Lesson 19 works out which operations keep a language context-free. It gives one-rule grammar constructions for union, concatenation, and star, with the variable-renaming condition, then the counterexample showing that intersection fails and why its shape is forced by the one-stack budget, and the De Morgan derivation of the failure of complement together with a concrete witness. It proves closure under intersection with a regular language by a product construction, flagging the trap of advancing the finite component on a free move, and covers reversal and the restricted form of difference. It ends with the full closure table read as a diagnostic for classifying languages.
Connect it up
Draw it
One page, no notation unless you need it: draw how these connect — Closure, Revisited · The Three Regular Operations · Intersection Fails · Complement Fails Too · Intersection With a Regular Language · The Table and How to Use It. Put an arrow wherever one of them is what makes another possible, and label the arrow with why.
Recap
You can say which operations keep a language context-free, and use the failures as classification tools.
| Situation | Move |
|---|---|
| combining two languages | grammars — one rule |
| restricting by a simple pattern | product with a finite automaton |
| restricting by another context-free language | not available — and often a proof that the result escapes |
| the complement looks easier than the language | suspect the language is outside the class |
| a language built only from closed operations | it is context-free, by the table |
Lesson 20 leaves both classes behind and introduces a machine with unrestricted memory — after which the interesting question stops being what can be recognized and becomes what can be decided.
Want this taught 1-on-1? Alexander tutors Theory of Computation — $55/session, free consultation.