Chomsky normal form
DefinitionChomsky normal form#✓fully proved
A grammar is in Chomsky normal form when every production has output either two nonterminals, a single terminal, or the empty word with the initial nonterminal on the left; and either the initial nonterminal occurs in no output (so an empty production cannot leak the empty word to other nonterminals) or there are no empty outputs at all.
def IsChomskyNormalForm (g : ContextFreeGrammar T) : Prop :=
(∀ r ∈ g.rules,
(∃ B C, r.output = [Symbol.nonterminal B, Symbol.nonterminal C]) ∨
(∃ a, r.output = [Symbol.terminal a]) ∨
(r.output = [] ∧ r.input = g.initial)) ∧
((∀ r ∈ g.rules, Symbol.nonterminal g.initial ∉ r.output) ∨
∀ r ∈ g.rules, r.output ≠ [])
Used by 16
DefinitionTerminals of a grammar#✓fully proved
For a context-free grammar \(G\), the list of terminals occurring in the outputs of its productions: going through the productions of \(G\) in a fixed but unspecified order, list the terminals of each output from left to right. A terminal may appear more than once.
noncomputable def grammarTerminals (g : ContextFreeGrammar T) : List T :=
g.rules.toList.flatMap fun r => r.output.filterMap fun s =>
match s with
| .terminal a => some a
| .nonterminal _ => none
Used by 13
DefinitionEncoding symbols as basic nonterminals of the binarized grammar#✓fully proved
Let \(G\) be a context-free grammar with nonterminals \(N\), and let \(t_0, \dots, t_{k-1}\) be the list of terminals occurring in the production outputs of \(G\). This map sends a symbol of \(G\) to an element of \(N \sqcup \mathbb{N}\): a nonterminal \(A\) goes to \(A\), and a terminal \(a\) goes to the least index \(i\) with \(t_i = a\), or to \(k\) if \(a\) does not occur in the list.
noncomputable def toCnfNT : Symbol T g.NT → g.NT ⊕ ℕ
| .terminal a => .inr ((grammarTerminals g).idxOf a)
| .nonterminal A => .inl A
noncomputable def grammarTerminals (g : ContextFreeGrammar T) : List T :=
g.rules.toList.flatMap fun r => r.output.filterMap fun s =>
match s with
| .terminal a => some a
| .nonterminal _ => none
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:66
Uses 1 · Used by 5
DefinitionDecoding basic nonterminals of the binarized grammar#✓fully proved
Let \(G\) be a context-free grammar with nonterminals \(N\) and initial nonterminal \(S\), and let \(t_0, \dots, t_{k-1}\) be the list of terminals occurring in the production outputs of \(G\). This map sends an element of \(N \sqcup \mathbb{N}\) (a basic nonterminal of the binarized grammar) to a symbol of \(G\): a nonterminal \(A \in N\) goes to \(A\), an index \(i < k\) goes to the terminal \(t_i\), and an index \(i \ge k\) goes to the nonterminal \(S\).
Indices \(i \ge k\) never arise from encoding nonterminals of \(G\) or terminals occurring in the production outputs of \(G\).
noncomputable def fromCnfNT : g.NT ⊕ ℕ → Symbol T g.NT
| .inl A => .nonterminal A
| .inr i => match (grammarTerminals g)[i]? with
| some a => .terminal a
| none => .nonterminal g.initial
noncomputable def grammarTerminals (g : ContextFreeGrammar T) : List T :=
g.rules.toList.flatMap fun r => r.output.filterMap fun s =>
match s with
| .terminal a => some a
| .nonterminal _ => none
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:66
Uses 1 · Used by 2
DefinitionHead of a binarized output#✓fully proved
Let \(g\) be a context-free grammar and let \(a_0, a_1, \dots\) be its list of terminals occurring in production outputs. For a list \(\sigma\) of basic symbols (each a nonterminal of \(g\) or a natural number, a terminal wrapper), the head \(h(\sigma)\) is the following form over the nonterminals of the binarized grammar (basic symbols and chain nonterminals \(\langle\tau\rangle\) for lists \(\tau\) of basic symbols): \(h(XY) = XY\) for two basic symbols \(X, Y\); \(h(XYZ\tau) = X\langle YZ\tau\rangle\) for basic symbols \(X, Y, Z\) and a list \(\tau\); \(h(i) = a_i\) for a single natural number \(i\) less than the length of the list; and \(h(\sigma)\) is empty in every other case (the empty list, a single nonterminal of \(g\), or a single out-of-range index).
noncomputable def cnfHead : List (g.NT ⊕ ℕ) →
List (Symbol T ((g.NT ⊕ ℕ) ⊕ List (g.NT ⊕ ℕ)))
| [] => []
| [B] => match B with
| .inr i => match (grammarTerminals g)[i]? with
| some a => [Symbol.terminal a]
| none => []
| .inl _ => []
| [B, C] => [Symbol.nonterminal (.inl B), Symbol.nonterminal (.inl C)]
| B :: C :: D :: σ =>
[Symbol.nonterminal (.inl B),
Symbol.nonterminal (.inr (C :: D :: σ))]
noncomputable def grammarTerminals (g : ContextFreeGrammar T) : List T :=
g.rules.toList.flatMap fun r => r.output.filterMap fun s =>
match s with
| .terminal a => some a
| .nonterminal _ => none
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:66
Uses 1 · Used by 5
DefinitionBinarization of a grammar#✓fully proved
Let \(g\) be a context-free grammar with nonterminals \(N\) and initial nonterminal \(S\), and let \(t_0, \dots, t_{k-1}\) be the list of terminals occurring in the production outputs of \(g\). Encode each symbol of a production output of \(g\) as a basic symbol in \(N \sqcup \mathbb{N}\): a nonterminal \(A\) as \(A\), and a terminal \(a\) as the least index \(i\) with \(t_i = a\). The binarized grammar of \(g\) has as nonterminals the basic symbols together with a chain nonterminal \(\langle\tau\rangle\) for every list \(\tau\) of basic symbols, and its initial nonterminal is \(S\). For a list \(\sigma\) of basic symbols, its head \(h(\sigma)\) is defined by \(h(XY) = XY\) and \(h(XYZ\tau) = X\langle YZ\tau\rangle\) for basic symbols \(X, Y, Z\) and a list \(\tau\), \(h(i) = t_i\) for a single index \(i < k\), and \(h(\sigma)\) empty in every other case. For every production \(A \to \alpha\) of \(g\), with \(\sigma\) the encoding of \(\alpha\) symbol by symbol, the binarized grammar has the production \(A \to h(\sigma)\), the production \(\langle\tau\rangle \to h(\tau)\) for every suffix \(\tau\) of \(\sigma\) (including \(\sigma\) itself) with at least two entries, and the production \(i \to a\) for every terminal \(a\) occurring in \(\alpha\), where \(i\) is the encoding of \(a\); it has no other productions.
This construction is meant for reduced grammars, which have no empty outputs and no outputs consisting of a single nonterminal: on other grammars such outputs get the empty head, and in general neither the language nor Chomsky normal form is preserved.
@[reducible] noncomputable def cnfGrammar (g : ContextFreeGrammar T) :
ContextFreeGrammar T where
NT := (g.NT ⊕ ℕ) ⊕ List (g.NT ⊕ ℕ)
initial := .inl (.inl g.initial)
rules := g.rules.biUnion fun r =>
{⟨.inl (.inl r.input), cnfHead (r.output.map toCnfNT)⟩} ∪
(((r.output.map toCnfNT).tails.filter fun σ => 2 ≤ σ.length).toFinset.image
fun σ => ⟨.inr σ, cnfHead σ⟩) ∪
(((r.output.filterMap fun s => match s with
| .terminal a => some a
| .nonterminal _ => none).toFinset.image
fun a => ⟨.inl (.inr ((grammarTerminals g).idxOf a)),
[Symbol.terminal a]⟩))
noncomputable def cnfHead : List (g.NT ⊕ ℕ) →
List (Symbol T ((g.NT ⊕ ℕ) ⊕ List (g.NT ⊕ ℕ)))
| [] => []
| [B] => match B with
| .inr i => match (grammarTerminals g)[i]? with
| some a => [Symbol.terminal a]
| none => []
| .inl _ => []
| [B, C] => [Symbol.nonterminal (.inl B), Symbol.nonterminal (.inl C)]
| B :: C :: D :: σ =>
[Symbol.nonterminal (.inl B),
Symbol.nonterminal (.inr (C :: D :: σ))]
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:121
noncomputable def toCnfNT : Symbol T g.NT → g.NT ⊕ ℕ
| .terminal a => .inr ((grammarTerminals g).idxOf a)
| .nonterminal A => .inl A
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:81
noncomputable def grammarTerminals (g : ContextFreeGrammar T) : List T :=
g.rules.toList.flatMap fun r => r.output.filterMap fun s =>
match s with
| .terminal a => some a
| .nonterminal _ => none
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:66
Uses 3 · Used by 5
DefinitionValuation of the binarized grammar by yields#✓fully proved
Let \(g\) be a context-free grammar and let \(a_0, a_1, \dots\) be its list of terminals occurring in production outputs. A basic symbol is a nonterminal of \(g\) or a natural number (a terminal wrapper); the nonterminals of the binarized grammar are the basic symbols together with a chain nonterminal \(\langle\sigma\rangle\) for every list \(\sigma\) of basic symbols. Decode a basic symbol as a symbol of \(g\): a nonterminal \(A\) of \(g\) as \(A\), a natural number \(i\) less than the length of the list as the terminal \(a_i\), and any other natural number as the initial nonterminal of \(g\). The valuation assigns to a basic symbol \(X\) the set of words that the decoding of \(X\) yields in \(g\), and to a chain nonterminal \(\langle\sigma\rangle\) the set of words that the symbolwise decoding of \(\sigma\) yields in \(g\).
noncomputable def cnfValuation :
(g.NT ⊕ ℕ) ⊕ List (g.NT ⊕ ℕ) → Language T
| .inl B => {w | Yields g [fromCnfNT B] w}
| .inr σ => {w | Yields g (σ.map fromCnfNT) w}
inductive Yields (g : ContextFreeGrammar T) : List (Symbol T g.NT) → List T → Prop
| nil : Yields g [] []
| terminal (a : T) {u : List (Symbol T g.NT)} {w : List T} (h : Yields g u w) :
Yields g (Symbol.terminal a :: u) (a :: w)
| nonterminal {r : ContextFreeRule T g.NT} (hr : r ∈ g.rules)
{u : List (Symbol T g.NT)} {w₁ w₂ : List T}
(hout : Yields g r.output w₁) (hrest : Yields g u w₂) :
Yields g (Symbol.nonterminal r.input :: u) (w₁ ++ w₂)
CSLibExt/Computability/Languages/ContextFree/Yields.lean:48
noncomputable def fromCnfNT : g.NT ⊕ ℕ → Symbol T g.NT
| .inl A => .nonterminal A
| .inr i => match (grammarTerminals g)[i]? with
| some a => .terminal a
| none => .nonterminal g.initial
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:88
Uses 2 · Used by 1
TheoremBinarization adds no words#✓fully proved
If a context-free grammar \(g\) is reduced, then every word generated by the binarization of \(g\) is generated by \(g\).
theorem cnfGrammar_language_le_of_reduced (hred : IsReduced g) :
(cnfGrammar g).language ≤ g.language
def IsReduced (g : ContextFreeGrammar T) : Prop :=
(∀ r ∈ g.rules, r.output ≠ []) ∧
∀ r ∈ g.rules, ¬ IsUnitOutput r.output
CSLibExt/Computability/Languages/ContextFree/Reduced.lean:472
@[reducible] noncomputable def cnfGrammar (g : ContextFreeGrammar T) :
ContextFreeGrammar T where
NT := (g.NT ⊕ ℕ) ⊕ List (g.NT ⊕ ℕ)
initial := .inl (.inl g.initial)
rules := g.rules.biUnion fun r =>
{⟨.inl (.inl r.input), cnfHead (r.output.map toCnfNT)⟩} ∪
(((r.output.map toCnfNT).tails.filter fun σ => 2 ≤ σ.length).toFinset.image
fun σ => ⟨.inr σ, cnfHead σ⟩) ∪
(((r.output.filterMap fun s => match s with
| .terminal a => some a
| .nonterminal _ => none).toFinset.image
fun a => ⟨.inl (.inr ((grammarTerminals g).idxOf a)),
⋯
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:160
Uses 16 · Used by 1
TheoremBinarization has no empty productions#✓fully proved
If a context-free grammar \(g\) is reduced, then no production of the binarization of \(g\) has the empty word as output.
theorem cnfGrammar_output_ne_nil (hred : IsReduced g) :
∀ ρ ∈ (cnfGrammar g).rules, ρ.output ≠ []
def IsReduced (g : ContextFreeGrammar T) : Prop :=
(∀ r ∈ g.rules, r.output ≠ []) ∧
∀ r ∈ g.rules, ¬ IsUnitOutput r.output
CSLibExt/Computability/Languages/ContextFree/Reduced.lean:472
@[reducible] noncomputable def cnfGrammar (g : ContextFreeGrammar T) :
ContextFreeGrammar T where
NT := (g.NT ⊕ ℕ) ⊕ List (g.NT ⊕ ℕ)
initial := .inl (.inl g.initial)
rules := g.rules.biUnion fun r =>
{⟨.inl (.inl r.input), cnfHead (r.output.map toCnfNT)⟩} ∪
(((r.output.map toCnfNT).tails.filter fun σ => 2 ≤ σ.length).toFinset.image
fun σ => ⟨.inr σ, cnfHead σ⟩) ∪
(((r.output.filterMap fun s => match s with
| .terminal a => some a
| .nonterminal _ => none).toFinset.image
fun a => ⟨.inl (.inr ((grammarTerminals g).idxOf a)),
⋯
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:160
Uses 6 · Used by 2
TheoremBinarization of a reduced grammar is in Chomsky normal form#✓fully proved
If a context-free grammar \(g\) is reduced, then the binarization of \(g\) is in Chomsky normal form.
theorem cnfGrammar_isChomskyNormalForm (hred : IsReduced g) :
IsChomskyNormalForm (cnfGrammar g)
def IsReduced (g : ContextFreeGrammar T) : Prop :=
(∀ r ∈ g.rules, r.output ≠ []) ∧
∀ r ∈ g.rules, ¬ IsUnitOutput r.output
CSLibExt/Computability/Languages/ContextFree/Reduced.lean:472
def IsChomskyNormalForm (g : ContextFreeGrammar T) : Prop :=
(∀ r ∈ g.rules,
(∃ B C, r.output = [Symbol.nonterminal B, Symbol.nonterminal C]) ∨
(∃ a, r.output = [Symbol.terminal a]) ∨
(r.output = [] ∧ r.input = g.initial)) ∧
((∀ r ∈ g.rules, Symbol.nonterminal g.initial ∉ r.output) ∨
∀ r ∈ g.rules, r.output ≠ [])
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:57
@[reducible] noncomputable def cnfGrammar (g : ContextFreeGrammar T) :
ContextFreeGrammar T where
NT := (g.NT ⊕ ℕ) ⊕ List (g.NT ⊕ ℕ)
initial := .inl (.inl g.initial)
rules := g.rules.biUnion fun r =>
{⟨.inl (.inl r.input), cnfHead (r.output.map toCnfNT)⟩} ∪
(((r.output.map toCnfNT).tails.filter fun σ => 2 ≤ σ.length).toFinset.image
fun σ => ⟨.inr σ, cnfHead σ⟩) ∪
(((r.output.filterMap fun s => match s with
| .terminal a => some a
| .nonterminal _ => none).toFinset.image
fun a => ⟨.inl (.inr ((grammarTerminals g).idxOf a)),
⋯
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:160
Uses 8 · Used by 1
TheoremBinarization preserves the language#✓fully proved
If a context-free grammar \(g\) is reduced, then the binarization of \(g\) generates exactly the language of \(g\).
theorem cnfGrammar_language_of_reduced (hred : IsReduced g) :
(cnfGrammar g).language = g.language
def IsReduced (g : ContextFreeGrammar T) : Prop :=
(∀ r ∈ g.rules, r.output ≠ []) ∧
∀ r ∈ g.rules, ¬ IsUnitOutput r.output
CSLibExt/Computability/Languages/ContextFree/Reduced.lean:472
@[reducible] noncomputable def cnfGrammar (g : ContextFreeGrammar T) :
ContextFreeGrammar T where
NT := (g.NT ⊕ ℕ) ⊕ List (g.NT ⊕ ℕ)
initial := .inl (.inl g.initial)
rules := g.rules.biUnion fun r =>
{⟨.inl (.inl r.input), cnfHead (r.output.map toCnfNT)⟩} ∪
(((r.output.map toCnfNT).tails.filter fun σ => 2 ≤ σ.length).toFinset.image
fun σ => ⟨.inr σ, cnfHead σ⟩) ∪
(((r.output.filterMap fun s => match s with
| .terminal a => some a
| .nonterminal _ => none).toFinset.image
fun a => ⟨.inl (.inr ((grammarTerminals g).idxOf a)),
⋯
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:160
Uses 22 · Used by 1
DefinitionGrammar with a fresh nullable start symbol#✓fully proved
Given a context-free grammar \(G\) with nonterminals \(N\) and initial nonterminal \(S\), this is the grammar with nonterminals \(N \cup \{S_0\}\) for a fresh symbol \(S_0\), initial nonterminal \(S_0\), and the following productions: every production of \(G\); the empty production \(S_0 \to \varepsilon\); and \(S_0 \to \alpha\) for every production \(S \to \alpha\) of \(G\).
The new grammar generates the language of \(G\) plus the empty word, and stays in Chomsky normal form when \(G\) is in Chomsky normal form and has no empty outputs.
@[reducible] noncomputable def epsStartGrammar (g : ContextFreeGrammar T) :
ContextFreeGrammar T where
NT := Option g.NT
initial := none
rules := (g.rules.map
⟨mapRule Option.some, mapRule_injective (Option.some_injective _)⟩) ∪
{⟨none, []⟩} ∪
((g.rules.filter fun r => r.input = g.initial).image fun r =>
⟨none, r.output.map (mapSymbol Option.some)⟩)
def mapRule {N' : Type*} (f : N → N') (r : ContextFreeRule T N) :
ContextFreeRule T N' :=
⟨f r.input, r.output.map (mapSymbol f)⟩
CSLibExt/Computability/Languages/ContextFree/Basic.lean:174
theorem mapRule_injective {N' : Type*} {f : N → N'} (hf : Function.Injective f) :
Function.Injective (mapRule (T := T) f)
CSLibExt/Computability/Languages/ContextFree/Basic.lean:274
def mapSymbol {N' : Type*} (f : N → N') : Symbol T N → Symbol T N'
| .terminal a => .terminal a
| .nonterminal A => .nonterminal (f A)
CSLibExt/Computability/Languages/ContextFree/Basic.lean:159
Uses 3 · Used by 5
TheoremLanguage of the grammar with a fresh nullable start symbol#✓fully proved
For every context-free grammar \(G\), the grammar obtained from \(G\) by adding a fresh initial nonterminal (with an empty production and copies of the productions of the old initial nonterminal) generates exactly \(L(G) \cup \{\varepsilon\}\), where \(L(G)\) is the language of \(G\) and \(\varepsilon\) is the empty word.
theorem epsStartGrammar_language (g : ContextFreeGrammar T) :
(epsStartGrammar g).language = insert [] g.language
@[reducible] noncomputable def epsStartGrammar (g : ContextFreeGrammar T) :
ContextFreeGrammar T where
NT := Option g.NT
initial := none
rules := (g.rules.map
⟨mapRule Option.some, mapRule_injective (Option.some_injective _)⟩) ∪
{⟨none, []⟩} ∪
((g.rules.filter fun r => r.input = g.initial).image fun r =>
⟨none, r.output.map (mapSymbol Option.some)⟩)
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:584
Uses 17 · Used by 2
TheoremThe fresh start symbol occurs in no output#✓fully proved
For every context-free grammar \(g\), the fresh initial nonterminal of the fresh-start grammar of \(g\) occurs in no production output of the fresh-start grammar.
theorem epsStartGrammar_initial_not_mem_output :
∀ ρ ∈ (epsStartGrammar g).rules,
Symbol.nonterminal (epsStartGrammar g).initial ∉ ρ.output
@[reducible] noncomputable def epsStartGrammar (g : ContextFreeGrammar T) :
ContextFreeGrammar T where
NT := Option g.NT
initial := none
rules := (g.rules.map
⟨mapRule Option.some, mapRule_injective (Option.some_injective _)⟩) ∪
{⟨none, []⟩} ∪
((g.rules.filter fun r => r.input = g.initial).image fun r =>
⟨none, r.output.map (mapSymbol Option.some)⟩)
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:584
Uses 4 · Used by 1
TheoremA fresh start symbol is harmless when the empty word is generated#✓fully proved
If the empty word belongs to the language of a context-free grammar \(g\), then the fresh-start grammar of \(g\) generates exactly the language of \(g\).
theorem epsStartGrammar_language_of_mem_nil
(hε : ([] : List T) ∈ g.language) :
(epsStartGrammar g).language = g.language
@[reducible] noncomputable def epsStartGrammar (g : ContextFreeGrammar T) :
ContextFreeGrammar T where
NT := Option g.NT
initial := none
rules := (g.rules.map
⟨mapRule Option.some, mapRule_injective (Option.some_injective _)⟩) ∪
{⟨none, []⟩} ∪
((g.rules.filter fun r => r.input = g.initial).image fun r =>
⟨none, r.output.map (mapSymbol Option.some)⟩)
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:584
Uses 2
TheoremAdding a fresh start symbol preserves Chomsky normal form#✓fully proved
If a context-free grammar \(g\) is in Chomsky normal form and no production of \(g\) has empty output, then the fresh-start grammar of \(g\) is in Chomsky normal form.
The no-empty-outputs hypothesis is essential: an existing empty production would be embedded with the old initial nonterminal, not the fresh one, on the left.
theorem epsStartGrammar_isChomskyNormalForm
(hCNF : IsChomskyNormalForm g)
(hne : ∀ r ∈ g.rules, r.output ≠ []) :
IsChomskyNormalForm (epsStartGrammar g)
def IsChomskyNormalForm (g : ContextFreeGrammar T) : Prop :=
(∀ r ∈ g.rules,
(∃ B C, r.output = [Symbol.nonterminal B, Symbol.nonterminal C]) ∨
(∃ a, r.output = [Symbol.terminal a]) ∨
(r.output = [] ∧ r.input = g.initial)) ∧
((∀ r ∈ g.rules, Symbol.nonterminal g.initial ∉ r.output) ∨
∀ r ∈ g.rules, r.output ≠ [])
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:57
@[reducible] noncomputable def epsStartGrammar (g : ContextFreeGrammar T) :
ContextFreeGrammar T where
NT := Option g.NT
initial := none
rules := (g.rules.map
⟨mapRule Option.some, mapRule_injective (Option.some_injective _)⟩) ∪
{⟨none, []⟩} ∪
((g.rules.filter fun r => r.input = g.initial).image fun r =>
⟨none, r.output.map (mapSymbol Option.some)⟩)
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:584
Uses 6 · Used by 1
TheoremChomsky normal form theorem#✓fully proved
For every context-free grammar \(G\) there is a context-free grammar in Chomsky normal form that generates the same language as \(G\).
theorem exists_chomskyNormalForm (g₀ : ContextFreeGrammar T) :
∃ g' : ContextFreeGrammar T, g'.language = g₀.language ∧
IsChomskyNormalForm g'
def IsChomskyNormalForm (g : ContextFreeGrammar T) : Prop :=
(∀ r ∈ g.rules,
(∃ B C, r.output = [Symbol.nonterminal B, Symbol.nonterminal C]) ∨
(∃ a, r.output = [Symbol.terminal a]) ∨
(r.output = [] ∧ r.input = g.initial)) ∧
((∀ r ∈ g.rules, Symbol.nonterminal g.initial ∉ r.output) ∨
∀ r ∈ g.rules, r.output ≠ [])
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:57
Uses 11 · Used by 1
TheoremChomsky normal form for context-free languages#✓fully proved
Every context-free language \(L\) is generated by some context-free grammar in Chomsky normal form.
theorem IsContextFree.exists_chomskyNormalForm {L : Language T}
(hL : L.IsContextFree) :
∃ g : ContextFreeGrammar T, g.language = L ∧
IsChomskyNormalForm g
def IsChomskyNormalForm (g : ContextFreeGrammar T) : Prop :=
(∀ r ∈ g.rules,
(∃ B C, r.output = [Symbol.nonterminal B, Symbol.nonterminal C]) ∨
(∃ a, r.output = [Symbol.terminal a]) ∨
(r.output = [] ∧ r.input = g.initial)) ∧
((∀ r ∈ g.rules, Symbol.nonterminal g.initial ∉ r.output) ∨
∀ r ∈ g.rules, r.output ≠ [])
CSLibExt/Computability/Languages/ContextFree/ChomskyNormalForm.lean:57
Uses 2
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.