Skip to content

Commit c77b102

Browse files
CFL pumping lemma — machine-checked from scratch in Lean (cfl_pumping) (#106)
## Summary Machine-checks the **pumping lemma for context-free languages** — a result even Mathlib lacks — built from scratch in core Lean (Mathlib-free, single-file, `lean docs/proofs/verification/WokeGrammarPumping.lean`). `cfl_pumping`: for an ε-free binary-normal-form grammar with `card` nonterminals, any word `z ∈ L(S)` of length `≥ 2^(card+1)` decomposes as `z = u v w x y` with - `1 ≤ |v x|` (the pumped part is non-empty — uses ε-freeness), - `|v w x| ≤ 2^(card+1)` (the window is bounded), - `u vⁱ w xⁱ y ∈ L(S)` for every `i`. ## What's in the file (`WokeGrammarPumping.lean`) Foundation (landed first): - parse trees `PT` over a binary-normal-form grammar; `yield_bound` (`|w| < 2^height`); - one-hole contexts `Ctx` + `fill`; `pumpIter` (the pumping operation); - `spine`/`spine_length`; a Mathlib-free finite `pigeon`hole. Assembly (this completes it): - `Ctx.comp` — context composition; - `descend` — tallest-spine descent (recursion on **depth** so it reduces definitionally); - `ht_descend` — descended-subtree height is `ht t − d`; - `nodeNT_add` — depth-composition law that locates the repeated nonterminal; - `yield_nonempty` / `descend_sibling_nonempty` — ε-free ⇒ `|v x| ≥ 1`; - `cfl_pumping` — pigeonhole over the bottom `card+1` spine nodes ⇒ outer·pump·base ⇒ pump via `pumpIter`. ## Trust base The three standard classical kernel constants (`propext`, `Classical.choice`, `Quot.sound`) — the same foundations Mathlib relies on (`Classical.choice` enters via the `pigeon` case split). No holes and no project-specific assumptions; every step is checked by Lean's kernel. ## Verification `lean docs/proofs/verification/WokeGrammarPumping.lean` exits 0 with no errors (wired into `.github/workflows/lean-proofs.yml`). Docs updated: `grammar-proofs.md` §7.3 and `GRAMMAR-PROOF-INVENTORY.md` record the pumping lemma as machine-checked. The §7.3 ∩/¬ non-closure corollary (finite `IsCFL` + `aⁿbⁿcⁿ ∉ CFL` + De Morgan) is the remaining increment, now unblocked. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_015oyMquf4daB6hMhmqB1wAL --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent dfcec84 commit c77b102

4 files changed

Lines changed: 420 additions & 7 deletions

File tree

.github/workflows/lean-proofs.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,9 @@ jobs:
6868
set -euo pipefail
6969
lean docs/proofs/verification/WokeGrammarCFL.lean
7070
echo "✅ WokeGrammarCFL.lean verified"
71+
72+
- name: Verify WokeGrammarPumping.lean (§7.3 non-closure: pumping foundation)
73+
run: |
74+
set -euo pipefail
75+
lean docs/proofs/verification/WokeGrammarPumping.lean
76+
echo "✅ WokeGrammarPumping.lean verified"

docs/proofs/formal-semantics/grammar-proofs.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,12 @@ The binding power comparison ensures this:
328328
> §7.3 **CFL closure under ∪, ·, \*** is now machine-checked too, in
329329
> [`../verification/WokeGrammarCFL.lean`](../verification/WokeGrammarCFL.lean)
330330
> (a CFG derivation relation + union/concat/star grammar constructions,
331-
> Mathlib-free, `sorry`-free). Only the §7.3 *non*-closure under ∩ / ¬ remains
332-
> scoped (it needs the pumping lemma for CFLs); status in
331+
> Mathlib-free, `sorry`-free). The **pumping lemma for context-free languages**
332+
> — which even Mathlib lacks — is now machine-checked from scratch in core Lean in
333+
> [`../verification/WokeGrammarPumping.lean`](../verification/WokeGrammarPumping.lean)
334+
> (`cfl_pumping`: parse-tree spine navigation + finite pigeonhole ⇒ the `uvwxy`
335+
> decomposition with `1 ≤ |vx|` and `|vwx| ≤ 2^(card+1)`). Only the §7.3 *non*-closure
336+
> under ∩ / ¬ remains, and the pumping lemma it needed is now available; status in
333337
> `../verification/GRAMMAR-PROOF-INVENTORY.md`.
334338
335339
### 7.1 Chomsky Hierarchy Position

docs/proofs/verification/GRAMMAR-PROOF-INVENTORY.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ reach here, with reason).
7171
| T1.2 | §1.1 LL(1) = ✗ || **P4** | Exhibit the FIRST/FIRST conflict (`primary → identifier` vs `identifier "(" …`) — a 1-lookahead non-determinism witness | MACHINE-CHECKED |
7272
| T7.3a | §7.3 CFL closed under ∪, ·, * | ✅ done from scratch | **P5→done** | `WokeGrammarCFL.lean`: CFG derivation relation + reusable embedding lemma + union/concat/star grammar constructions, `propext`-only | MACHINE-CHECKED |
7373
| T7.1 | §7.1 Not regular (pumping lemma) | ✅ done from scratch | **P6→done** | `WokeGrammarRegular.lean`: bespoke finite pigeonhole + `Fin k` DFA + fooling-set on `aⁿbⁿ` (≅ `(ⁿ)ⁿ`), Mathlib-free | MACHINE-CHECKED |
74-
| T7.3b | §7.3 CFL **not** closed under ∩, ¬ | ⚠️ no (needs non-CFL-ness of `aⁿbⁿcⁿ`) | **P6** | Requires the pumping lemma *for CFLs* — same Mathlib gap | FLAGGED |
74+
| T7.0 | CFL pumping lemma (Mathlib-gap) | ✅ done from scratch | **Ext** | `WokeGrammarPumping.lean`: `cfl_pumping``descend`/`ht_descend`/`nodeNT_add` spine navigation + `Ctx.comp` + pigeonhole ⇒ `z = uvwxy`, `1≤|vx|`, `|vwx|≤2^(card+1)`, `uvⁱwxⁱy ∈ L`; classical kernel constants only | MACHINE-CHECKED |
75+
| T7.3b | §7.3 CFL **not** closed under ∩, ¬ | ⚠️ remaining (pumping lemma now available) | **P6** | The blocker (CFL pumping lemma) is now proved as T7.0; remaining: finite `IsCFL` + `aⁿbⁿcⁿ ∉ CFL` + De Morgan | IN PROGRESS |
7576

7677
## Priority order (execution)
7778

@@ -162,7 +163,7 @@ universal `prefix_rt`/`completeness_rp` development; a Coq port of that is the
162163
scoped next step, exactly as `WokeLang.{lean,v}` are "complementary, not
163164
identical" per `AUDIT.md`.)
164165

165-
## §7 — status (T7.1 done from scratch; §7.3 scoped)
166+
## §7 — status (T7.1 done; §7.3 positive closure + CFL pumping lemma done)
166167

167168
- **T7.1 not regular — DONE** (`WokeGrammarRegular.lean`): rather than fetch
168169
Mathlib's automata library (blocked offline), a bespoke finite pigeonhole + a
@@ -174,9 +175,22 @@ identical" per `AUDIT.md`.)
174175
(`embGen_iff`) + explicit union/concat/star grammar constructions, `sorry`-free
175176
(`propext`-only). The WokeLang surface grammar is context-free, so it inhabits
176177
this class and these operations apply.
177-
- **§7.3 *non-closure* under ∩ / ¬** is still scoped: it needs the pumping lemma
178-
**for CFLs** (e.g. to show `aⁿbⁿcⁿ` is not context-free), a separate larger
179-
development — recorded rather than stubbed.
178+
- **Pumping lemma for CFLs — DONE** (`WokeGrammarPumping.lean`): the full pumping
179+
lemma (which even Mathlib lacks) is now machine-checked from scratch in core
180+
Lean. `cfl_pumping` states that for an ε-free binary-normal-form grammar with
181+
`card` nonterminals, any word `z ∈ L(S)` of length `≥ 2^(card+1)` splits as
182+
`z = u v w x y` with `1 ≤ |v x|`, `|v w x| ≤ 2^(card+1)`, and `u vⁱ w xⁱ y ∈
183+
L(S)` for all `i`. Engine: parse trees + `|w| < 2^height` yield bound + one-hole
184+
contexts/`fill`/`comp` + `pumpIter` + tallest-spine `descend` (with the
185+
`ht = height − depth` and depth-composition laws) + finite pigeonhole ⇒
186+
repeated-nonterminal extraction. Trust base: the three classical kernel
187+
constants (`propext`, `Classical.choice`, `Quot.sound`) — no holes, no
188+
project-specific assumptions.
189+
- **§7.3 *non-closure* under ∩ / ¬** is the remaining increment. With the pumping
190+
lemma in hand it follows by the standard route: a finiteness-aware `IsCFL` (the
191+
relation-based `IsCFL` is too permissive here — an infinite nonterminal type
192+
could "generate" `aⁿbⁿcⁿ`), then `aⁿbⁿcⁿ ∉ CFL` via `cfl_pumping`, then
193+
`L₁ ∩ L₂` non-closure by De Morgan against the proven positive ∪ closure.
180194

181195
## Status
182196

0 commit comments

Comments
 (0)