Algorithm Search⌘K

Proofs: Closure properties of context-free languages

These are the human proofs of Closure properties of context-free languages, at full length.

Proof of the closure properties of context-free languages full

This proof shows: statement.

Throughout, G=(V,Σ,R,S)G = (V, \Sigma, R, S), G1=(V1,Σ,R1,S1)G_1 = (V_1, \Sigma, R_1, S_1) and G2=(V2,Σ,R2,S2)G_2 = (V_2, \Sigma, R_2, S_2) are grammars for LL, L1L_1 and L2L_2, renamed so that their nonterminal sets are disjoint from each other and from every new symbol. We use one fact about grammars many times.

Fact (context-freeness). If X1⋯Xk⇒∗wX_1 \cdots X_k \Rightarrow^* w, then w=w1⋯wkw = w_1 \cdots w_k with Xi⇒∗wiX_i \Rightarrow^* w_i for each ii, and each derivation Xi⇒∗wiX_i \Rightarrow^* w_i uses at most as many steps as the whole. Conversely, derivations Xi⇒∗wiX_i \Rightarrow^* w_i combine into X1⋯Xk⇒∗w1⋯wkX_1 \cdots X_k \Rightarrow^* w_1 \cdots w_k. This holds because a step rewrites one nonterminal and does not look at its neighbours, so the steps can be sorted by the symbol XiX_i they descend from.

1. Union, concatenation and star

Let SS be a new start symbol.

  • Union. Add S→S1∣S2S \to S_1 \mid S_2 to R1∪R2R_1 \cup R_2. A derivation from SS starts with one of the two productions and then uses only the productions of that grammar, because the nonterminal sets are disjoint. So the language is L1∪L2L_1 \cup L_2.
  • Concatenation. Add S→S1S2S \to S_1 S_2. By the Fact, S1S2⇒∗wS_1 S_2 \Rightarrow^* w exactly when w=w1w2w = w_1 w_2 with S1⇒∗w1S_1 \Rightarrow^* w_1 and S2⇒∗w2S_2 \Rightarrow^* w_2. The language is L1L2L_1 L_2.
  • Star. Add S→S1S∣εS \to S_1 S \mid \varepsilon to R1R_1. By induction on kk, S⇒∗S1kSS \Rightarrow^* S_1^k S, so SS derives every string of L1kL_1^k for every k≥0k \ge 0. Conversely, a derivation from SS uses S→S1SS \to S_1 S some kk times and S→εS \to \varepsilon once, since that is the only way to remove SS, so by the Fact the string is in L1kL_1^k. The language is L1∗L_1^*.

2. Reversal

Replace each production A→X1⋯XkA \to X_1 \cdots X_k by A→Xk⋯X1A \to X_k \cdots X_1. By induction on the length of the derivation, A⇒∗wA \Rightarrow^* w in the old grammar exactly when A⇒∗wRA \Rightarrow^* w^R in the new one: the first step A→X1⋯XkA \to X_1 \cdots X_k with Xi⇒∗wiX_i \Rightarrow^* w_i becomes A→Xk⋯X1A \to X_k \cdots X_1 with Xi⇒∗wiRX_i \Rightarrow^* w_i^R, and wkR⋯w1R=(w1⋯wk)Rw_k^R \cdots w_1^R = (w_1 \cdots w_k)^R. The language is LRL^R.

3. Substitution and homomorphism

Let ss map each a∈Σa \in \Sigma to a context-free language s(a)⊆Δ∗s(a) \subseteq \Delta^* with grammar Ga=(Va,Δ,Ra,Sa)G_a = (V_a, \Delta, R_a, S_a), and extend it by s(ε)={ε}s(\varepsilon) = \{\varepsilon\}, s(xy)=s(x)s(y)s(xy) = s(x) s(y) and s(L)=⋃x∈Ls(x)s(L) = \bigcup_{x \in L} s(x). The grammar GsG_s has nonterminals V∪⋃aVaV \cup \bigcup_a V_a, start symbol SS, the productions of every GaG_a, and each production of GG with every terminal aa replaced by SaS_a.

If x=a1⋯ak∈Lx = a_1 \cdots a_k \in L and yi∈s(ai)y_i \in s(a_i), then S⇒∗Sa1⋯SakS \Rightarrow^* S_{a_1} \cdots S_{a_k} in GsG_s, by the derivation of xx with the replaced productions, and then Sai⇒∗yiS_{a_i} \Rightarrow^* y_i, so y1⋯yky_1 \cdots y_k is derived. Conversely, take a parse tree of yy in GsG_s. The nodes labelled by nonterminals of VV form a tree at the top whose leaves are labelled by symbols Sa1,…,SakS_{a_1}, \ldots, S_{a_k} in order, because the productions of VV only produce symbols of VV and start symbols SaS_a, and the productions of each GaG_a never produce a symbol of VV. Replacing each SaiS_{a_i} by aia_i turns the top tree into a parse tree of x=a1⋯akx = a_1 \cdots a_k in GG, and the subtree below each SaiS_{a_i} shows yi∈s(ai)y_i \in s(a_i), with y=y1⋯yky = y_1 \cdots y_k. So L(Gs)=s(L)L(G_s) = s(L).

A homomorphism hh is the substitution with s(a)={h(a)}s(a) = \{h(a)\}, and {h(a)}\{h(a)\} has the grammar Sa→h(a)S_a \to h(a). So h(L)h(L) is context-free.

4. Intersection with a regular language

Let D=(Q,Σ,δ,q0,F)D = (Q, \Sigma, \delta, q_0, F) be a DFA for RR, with δ\delta a partial function. The grammar G∩G_\cap has a new start symbol S′S' and the nonterminals [pXq][p X q] for p,q∈Qp, q \in Q and X∈V∪ΣX \in V \cup \Sigma, with the productions

  • S′→[q0Sf]S' \to [q_0 S f] for each f∈Ff \in F;
  • [paq]→a[p a q] \to a whenever δ(p,a)=q\delta(p, a) = q;
  • [pAp]→ε[p A p] \to \varepsilon for each A→εA \to \varepsilon in RR and each p∈Qp \in Q;
  • [p0Apk]→[p0X1p1][p1X2p2]⋯[pk−1Xkpk][p_0 A p_k] \to [p_0 X_1 p_1][p_1 X_2 p_2] \cdots [p_{k-1} X_k p_k] for each A→X1⋯XkA \to X_1 \cdots X_k in RR with k≥1k \ge 1 and all states p0,…,pkp_0, \ldots, p_k.

Claim. [pXq]⇒∗w[p X q] \Rightarrow^* w in G∩G_\cap if and only if X⇒∗wX \Rightarrow^* w in GG (or X=wX = w for a terminal XX) and δ∗(p,w)=q\delta^*(p, w) = q.

Proof. "Only if", by induction on the length of the derivation. For a terminal X=aX = a, the only production is [paq]→a[p a q] \to a with δ(p,a)=q\delta(p, a) = q. For X=AX = A, the first step uses a production that comes from some A→X1⋯XkA \to X_1 \cdots X_k. If k=0k = 0 then w=εw = \varepsilon, q=pq = p, and δ∗(p,ε)=p\delta^*(p, \varepsilon) = p. Otherwise, by the Fact, w=w1⋯wkw = w_1 \cdots w_k with [pi−1Xipi]⇒∗wi[p_{i-1} X_i p_i] \Rightarrow^* w_i by shorter derivations, so by induction Xi⇒∗wiX_i \Rightarrow^* w_i and δ∗(pi−1,wi)=pi\delta^*(p_{i-1}, w_i) = p_i. Then A⇒X1⋯Xk⇒∗wA \Rightarrow X_1 \cdots X_k \Rightarrow^* w and δ∗(p,w)=pk=q\delta^*(p, w) = p_k = q.

"If", by induction on the length of the derivation X⇒∗wX \Rightarrow^* w in GG, with terminals as the base case. If X=AX = A and the first step is A→X1⋯XkA \to X_1 \cdots X_k, then w=w1⋯wkw = w_1 \cdots w_k with Xi⇒∗wiX_i \Rightarrow^* w_i by shorter derivations. Let p0=pp_0 = p and pi=δ∗(pi−1,wi)p_i = \delta^*(p_{i-1}, w_i), which is defined because δ∗(p,w)\delta^*(p, w) is, and pk=qp_k = q. By induction [pi−1Xipi]⇒∗wi[p_{i-1} X_i p_i] \Rightarrow^* w_i, and the production [pAq]→[p0X1p1]⋯[pk−1Xkpk][p A q] \to [p_0 X_1 p_1] \cdots [p_{k-1} X_k p_k], or [pAp]→ε[p A p] \to \varepsilon when k=0k = 0, finishes. □\square

With X=SX = S, p=q0p = q_0 and q∈Fq \in F, the claim gives L(G∩)=L∩RL(G_\cap) = L \cap R.

5. Inverse homomorphism

Let g:Δ∗→Σ∗g : \Delta^* \to \Sigma^* be a homomorphism, and let P=(Q,Σ,Γ,δ,q0,Z0,F)P = (Q, \Sigma, \Gamma, \delta, q_0, Z_0, F) be a PDA with L(P)=LL(P) = L, which exists by the equivalence of grammars and pushdown automata. Let BB be the finite set of suffixes of the strings g(a)g(a), a∈Δa \in \Delta, including ε\varepsilon. The PDA P′P' has states Q×BQ \times B, start state (q0,ε)(q_0, \varepsilon), start symbol Z0Z_0, final states F×{ε}F \times \{\varepsilon\}, and three kinds of moves, for all X∈ΓX \in \Gamma:

  • (load) ((q,g(a)),X)∈δ′((q,ε),a,X)((q, g(a)), X) \in \delta'((q, \varepsilon), a, X) for each q∈Qq \in Q and a∈Δa \in \Delta;
  • (step) ((p,u),γ)∈δ′((q,bu),ε,X)((p, u), \gamma) \in \delta'((q, b u), \varepsilon, X) whenever (p,γ)∈δ(q,b,X)(p, \gamma) \in \delta(q, b, X) with b∈Σb \in \Sigma and bu∈Bb u \in B;
  • (silent) ((p,u),γ)∈δ′((q,u),ε,X)((p, u), \gamma) \in \delta'((q, u), \varepsilon, X) whenever (p,γ)∈δ(q,ε,X)(p, \gamma) \in \delta(q, \varepsilon, X), for each u∈Bu \in B.

The second component is a buffer that holds the part of g(a)g(a) that PP has not read yet.

Claim. P′P' accepts x∈Δ∗x \in \Delta^* if and only if PP accepts g(x)g(x).

Proof. Given an accepting run of P′P' on x=a1⋯akx = a_1 \cdots a_k, delete the load moves and drop the buffer from each state. A step move becomes the move of PP that reads the first symbol bb of the buffer, and a silent move becomes the same silent move of PP. The buffer is loaded with g(ai)g(a_i) only when it is empty, and its symbols are removed in order, so the moves of PP read g(a1)g(a2)⋯g(ak)=g(x)g(a_1) g(a_2) \cdots g(a_k) = g(x). The run ends in a state (q,ε)(q, \varepsilon) with q∈Fq \in F, so all of g(x)g(x) was read and PP accepts.

Conversely, take an accepting run of PP on g(x)g(x). Build a run of P′P' by induction along it, keeping the invariant: after the moves of PP that have read g(a1)⋯g(ai−1) vg(a_1) \cdots g(a_{i-1})\, v, where vv is a prefix of g(ai)g(a_i) and g(ai)=vug(a_i) = v u, the run of P′P' has read a1⋯aia_1 \cdots a_i (or a1⋯ai−1a_1 \cdots a_{i-1} with an empty buffer if v=εv = \varepsilon and aia_i is not loaded yet), its state is (q,u)(q, u) for the current state qq of PP, and its stack is that of PP. A silent move of PP is copied as a silent move. Before a move of PP that reads a symbol bb, while the buffer is empty, load the next symbols aia_i of xx; loads of symbols with g(ai)=εg(a_i) = \varepsilon keep the buffer empty, and the first load with g(ai)≠εg(a_i) \ne \varepsilon puts g(ai)g(a_i), which starts with bb, into the buffer; then copy the move as a step move. At the end of the run of PP, load the remaining symbols of xx, whose images are all ε\varepsilon, since PP has read all of g(x)g(x). The final state is (q,ε)(q, \varepsilon) with q∈Fq \in F, so P′P' accepts xx. □\square

So g−1(L)=L(P′)g^{-1}(L) = L(P') is context-free.

6. Failure for intersection, complement and difference

Let L1={aibicj:i,j≥0}L_1 = \{a^i b^i c^j : i, j \ge 0\}, with the grammar S→XCS \to X C, X→aXb∣εX \to a X b \mid \varepsilon, C→cC∣εC \to c C \mid \varepsilon, and L2={aibjcj:i,j≥0}L_2 = \{a^i b^j c^j : i, j \ge 0\}, with the grammar S→AYS \to A Y, A→aA∣εA \to a A \mid \varepsilon, Y→bYc∣εY \to b Y c \mid \varepsilon. Both are context-free. Their intersection is {anbncn:n≥0}\{a^n b^n c^n : n \ge 0\}, which is not context-free by the pumping lemma. So the class is not closed under intersection.

If it were closed under complement, then by part 1 it would contain L1‾∪L2‾‾=L1∩L2\overline{\overline{L_1} \cup \overline{L_2}} = L_1 \cap L_2, a contradiction. And L‾=Σ∗∖L\overline{L} = \Sigma^* \setminus L with Σ∗\Sigma^* context-free, so closure under difference would give closure under complement. ■\blacksquare

Back to Closure properties of context-free languages