Context-Free Right Quotients #
This file proves the sharp closure behavior for right quotients of context-free languages:
- CFLs are closed under right quotient with regular languages: if
Lis context-free andRis regular, thenL / Ris context-free. - CFLs are not closed under right quotient with context-free languages.
Regular Quotient Strategy #
For the positive theorem, we use an abstract, closure-property-based proof.
The key idea is to "tag" each letter
with whether it belongs to the kept prefix (Sum.inl) or the removed suffix (Sum.inr),
then intersect with a regular "block" language that enforces the structure and R-membership,
and finally erase the suffix tags via substitution.
Concretely, given a CFL L over T and a regular language R over T:
Tag substitution
σ : T → Language (T ⊕ T)maps each letterato{[inl a], [inr a]}. Since eachσ(a)is CF,L.subst σis CF (byCF_of_subst_CF).Block language
blockLang RoverT ⊕ Tconsists of words of the formu.map inl ++ v.map inrwherev ∈ R. This is regular (we construct a DFA).Intersection:
L.subst σ ⊓ blockLang Ris CF (CF ∩ Regular = CF).Erasure
η : (T ⊕ T) → Language Tkeepsinl-tagged letters and erasesinr-tagged ones. Since eachη(x)is CF,(L.subst σ ⊓ blockLang R).subst ηis CF.Correctness:
(L.subst σ ⊓ blockLang R).subst η = L / R.
CFL Quotient Counterexample #
For the negative theorem, the witness is
quotientNumerator / quotientDenominator, where
quotientNumerator = {a^(2n)b^n | n ≥ 1}*quotientDenominator = {b^n a^n | n ≥ 1}* {b}
with false = a and true = b. Both languages are CFLs. Their quotient has unary
regular slice exactly {a^(2^(k+1)) | k ∈ ℕ}, which is not CFL by the pumping lemma.
Main declarations #
blockLang— the regular "block" languageblockLangDFA— a DFA recognisingblockLang Ris_CF_rightQuotient_regular— the main theorem (is_CFformulation)Language.IsContextFree.rightQuotient_regular— Mathlib-style formulationquotient_slice_eq_unaryPow2— identifies the unary slice of the CFL/CFL quotientCF_notClosedUnderRightQuotient— CFLs are not closed under right quotient by CFLs
Given a DFA D for R, build a DFA over T ⊕ T that recognises blockLang (D.accepts).
States: Option (Bool × σ) where
some (false, q)= phase 1 (readinginl-tagged letters), DFA stateqsome (true, q)= phase 2 (readinginr-tagged letters), DFA stateqnone= dead (sawinlafterinr)
Equations
- One or more equations did not get rendered due to their size.
Instances For
Context-free languages are closed under right quotient with regular languages
(Mathlib-style Language.IsContextFree formulation).
prefixLang as a special case: if L is CF, then prefixLang L is CF.
The class of context-free languages is closed under right quotient with regular languages.
Standard CFL/CFL quotient witnesses #
The eventual counterexample uses
({a^(2n)b^n | n ∈ ℕ})* / (({b^n a^n | n ∈ ℕ})* {b}).
The unary slice of this quotient is unaryPow2.
Flattened concatenation of positive left-block sizes.
Equations
- quotientLeftBlocks ns = (List.map (fun (n : ℕ) => List.replicate (2 * n) false ++ List.replicate n true) ns).flatten
Instances For
Flattened concatenation of positive right-block sizes.
Equations
- quotientRightBlocks ns = (List.map (fun (n : ℕ) => List.replicate n true ++ List.replicate n false) ns).flatten
Instances For
Denominator blocks for the explicit suffix witnessing
a^(2^(k+1)) ∈ quotientNumerator / quotientDenominator.
Equations
- quotientRightWitnessBlocks 0 = []
- quotientRightWitnessBlocks k.succ = (List.replicate (2 ^ (k + 1)) true ++ List.replicate (2 ^ (k + 1)) false) :: quotientRightWitnessBlocks k
Instances For
The suffix b^(2^k)a^(2^k) ... b²a² b used for the forward slice inclusion.
Equations
Instances For
Numerator blocks matching a^(2^(k+1)) ++ quotientWitnessSuffix k.
Equations
- quotientLeftWitnessBlocks 0 = [List.replicate 2 false ++ [true]]
- quotientLeftWitnessBlocks k.succ = (List.replicate (2 ^ (k + 2)) false ++ List.replicate (2 ^ (k + 1)) true) :: quotientLeftWitnessBlocks k
Instances For
The regular unary language a*, with false = a.
Equations
Instances For
Since the quotient's unary regular slice is unaryPow2, the quotient cannot be CFL.
CFLs are not closed under right quotient by CFLs.