Skip to content

proofs(lean4): close ET-2 — L1 conversion is decidable - #24

Merged
hyperpolymath merged 1 commit into
proofs/lean4-l1-l2from
proofs/et2-conversion-et14-tea
Jul 22, 2026
Merged

proofs(lean4): close ET-2 — L1 conversion is decidable#24
hyperpolymath merged 1 commit into
proofs/lean4-l1-l2from
proofs/et2-conversion-et14-tea

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Closes obligation ET-2 (decidability of L1 conversion) for the mechanized core calculus. This was the upstream blocker sitting under ET-14 / Phase 6.

Stacking and provenance

  • Base is proofs/lean4-l1-l2, not main. That branch is pushed but has no PR of its own; this stacks on it so the mechanization lands as one reviewable lineage. Retarget to main if proofs/lean4-l1-l2 merges first.
  • Produced by a parallel proof campaign (four independent max-effort attempts, lake build as the judge). Two attempts reached full closure; this is the stronger one (38 theorems, faithful Keller–Altenkirch decomposition). Attempt artefacts were written to a scratch directory and applied here by hand — the campaign's own verify and adversarial-review stages were cut short by a monthly spend limit, so every check below was re-run manually rather than taken on an agent's word.

What landed

Purely additive — Syntax/Normal/Hsub/Conversion.lean are byte-identical; the only edits to existing files are append-only registry entries (18 insertions, 0 deletions).

File Contents
Systemet/L1/SubstLemmas.lean substitution/weakening exchange family, incl. nf_substTy — normalization commutes with hereditary substitution (the whole content of the beta case)
Systemet/L1/Soundness.lean soundness : DefEq t (embNf (nf t))
Systemet/L1/Completeness.lean completeness : DefEq t u → nf t = nf u; defEq_iff_nf : DefEq t u ↔ nf t = nf u
Systemet/L1/Decidable.lean decEqNf / decEqSp (hand-rolled mutual DecidableEqderiving does not work across the Nf/Sp pair); decDefEq : (t u : Ty Γ k) → Decidable (DefEq t u)

File layout matches the slots the ET-2 ledger entry already named.

Evidence (measured)

  • Clean rebuild after rm -rf .lake/build: Build completed successfully (16 jobs)
  • scripts/check-proofs.sh lean4PASS, audit reports 20/20 headline items within the trusted base
  • scripts/scan-dangerous.shPASS
  • scripts/check-proof-status.shPASS (exit 0) after the PROOF-STATUS.adoc update
  • #print axioms on soundness, completeness, defEq_iff_nf, decDefEq, decEqNf, decEqSp, nf_substTy[propext, Quot.sound] only. No sorryAx, no user axioms, and not even Classical.choice.
  • Checked for a shadowed DefEq/nf: none — the new theorems quantify over the originals from Conversion.lean, with general Γ and k and no added hypotheses.

Scope — what this does not claim

DefEq here is β + equivalence + congruence. η is not included, and remains an OPEN row. ET-3 is unaffected — its η and model directions stay open. PROOF-STATUS.adoc marks ET-2 proven for the L1 core calculus, under the caveat that file already carries about core-vs-full-theory claims, and drops the now-satisfied "ET-2 (finish)" OPEN row.

ET-14 (TEA erasure) is untouched and remains the headline open problem. The campaign's TEA design track produced nothing — all three panelists and the judge died on the spend limit — so the ET-16 / L0 lowering ADR is still owner-gated and unstarted.

🤖 Generated with Claude Code

Completes the MECH-1 milestone that Conversion.lean recorded as open.
Purely additive: four new modules under Systemet/L1/, plus append-only
entries in Systemet.lean, MANIFEST and Audit.lean. Syntax/Normal/Hsub/
Conversion.lean are untouched.

Landed (all statements verbatim from the ET-2 ledger entry):
  SubstLemmas.lean  substitution/weakening exchange family, incl.
                    nf_substTy — normalization commutes with hereditary
                    substitution (the beta case's whole content)
  Soundness.lean    soundness : DefEq t (embNf (nf t))
  Completeness.lean completeness : DefEq t u -> nf t = nf u
                    defEq_iff_nf : DefEq t u <-> nf t = nf u
  Decidable.lean    decEqNf / decEqSp (hand-rolled mutual DecidableEq --
                    `deriving` does not work across the Nf/Sp pair)
                    decDefEq : (t u : Ty G k) -> Decidable (DefEq t u)

Method: exchange coordinates (swp/remSwap) with an Eq.rec cast toolkit
whose push lemmas are all `by subst h; rfl`, so definitional proof
irrelevance makes diagonal casts vanish. The subst/subst exchange needs a
SUM measure (kindSize k + kindSize b, tag, size) because the miss-then-hit
case folds appSp at the second kind.

Evidence (measured, not asserted):
  clean rebuild from scratch  Build completed successfully (16 jobs)
  scripts/check-proofs.sh     PASS, 20/20 headline items in trusted base
  scripts/scan-dangerous.sh   PASS
  scripts/check-proof-status  PASS after the doc update below
  #print axioms on soundness, completeness, defEq_iff_nf, decDefEq,
  decEqNf, decEqSp, nf_substTy -> [propext, Quot.sound] only; no
  sorryAx, no user axioms, no Classical.choice.

Scope, stated honestly: DefEq here is beta + equivalence + congruence.
eta is NOT included and remains an OPEN row, so ET-3 is unaffected --
its eta and model directions stay open. PROOF-STATUS.adoc moves ET-2 to
proven *for the L1 core calculus* under the file's existing core-vs-full-
theory caveat, and the now-satisfied "ET-2 (finish)" OPEN row is removed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@hyperpolymath
hyperpolymath marked this pull request as ready for review July 22, 2026 08:41
@hyperpolymath
hyperpolymath merged commit 7599b7b into proofs/lean4-l1-l2 Jul 22, 2026
24 of 28 checks passed
@hyperpolymath
hyperpolymath deleted the proofs/et2-conversion-et14-tea branch July 22, 2026 08:41
hyperpolymath added a commit that referenced this pull request Jul 27, 2026
Promotes the **ET-2 closure** (decidability of L1 conversion) onto
`main`.

## Why this PR exists

ET-2 was proven and merged in **PR #24** — but into
`proofs/lean4-l1-l2`, **not `main`**. PR #17 had squash-merged that
branch to `main` *before* ET-2 existed, so `main` holds the L1/L2
mechanization content while the ET-2 work sits only on the branch. No
second PR to `main` was ever opened.

Measured before this PR: `main...proofs/lean4-l1-l2` was **diverged, 4
ahead / 14 behind**, and all four ET-2 proof files returned **404 on
`main`**. Anything reading `main` today correctly concludes ET-2 is
still open.

## What lands on `main`

| File | Contents |
|---|---|
| `Systemet/L1/SubstLemmas.lean` | substitution/weakening exchange
family, incl. `nf_substTy` — normalization commutes with hereditary
substitution (the whole content of the β case) |
| `Systemet/L1/Soundness.lean` | `soundness : DefEq t (embNf (nf t))` |
| `Systemet/L1/Completeness.lean` | `completeness : DefEq t u → nf t =
nf u`; `defEq_iff_nf : DefEq t u ↔ nf t = nf u` |
| `Systemet/L1/Decidable.lean` | `decEqNf` / `decEqSp` (hand-rolled
mutual `DecidableEq` — `deriving` does not work across the `Nf`/`Sp`
pair); `decDefEq : (t u : Ty Γ k) → Decidable (DefEq t u)` |

Plus the `PROOF-STATUS.adoc` truth pass (`gated` 11 → 15, ET-2 row
proven, MECH-1 row landed, the satisfied `ET-2 (finish)` OPEN row
removed) and append-only `MANIFEST` / `Systemet.lean` / `Audit.lean`
entries.

## Conflict resolution — read this bit

The pre-PR sync merge (`0104c9c`) hit five conflicts. **Four were
`add/add` artefacts of the squash in #17**, which makes git treat both
sides as independent additions. None were resolved by a blanket
`--ours`/`--theirs`:

- `MANIFEST`, `Systemet.lean`, `Audit.lean` — verified `main`'s content
is **byte-identical** to the branch's and the branch is a **strict
superset** (adds exactly the four ET-2 entries). Branch side taken.
- `PROOF-STATUS.adoc` — every difference is this branch's ET-2 update;
`main` carried no independent edits. Branch side taken.
- **`.github/workflows/proofs.yml` — a genuine two-sided merge.** The
sides differed in *opposite* directions: `main` had the newer
`actions/checkout@3d3c42e` (v7.0.1, from dependabot #26) while the
branch had `curl --proto '=https' --tlsv1.2` (the Sonar S6506 fix). Took
main's newer pin **and** re-applied the branch's https hardening, so
neither is regressed. Both confirmed present post-resolution.

## Evidence (measured on the merged tree, not inherited from #24)

- Cold rebuild after `rm -rf .lake/build` → **Build completed
successfully (16 jobs)**
- `scripts/check-proofs.sh lean4` → **PASS** (real exit 0); audit
reports **20/20 headline items within the trusted base**
- `scripts/scan-dangerous.sh` → **PASS** (real exit 0)
- `scripts/check-proof-status.sh` → **PASS** (real exit 0) — 15 gated,
document agrees
- Forbidden-token scan on the four new proof files → clean
- `#print axioms` on `soundness`, `completeness`, `defEq_iff_nf`,
`decDefEq`, `decEqNf`, `decEqSp`, `nf_substTy` → **`[propext,
Quot.sound]` only**; no `sorryAx`, no user axioms, not even
`Classical.choice`

Real exit codes were checked directly — piping a gate through `tail` and
reading `$?` reports *tail's* status, which is how a red gate can look
green.

## Scope — what this does *not* claim

`DefEq` here is **β + equivalence + congruence. η is not included** and
remains an OPEN row. **ET-3 is unaffected** — its η and model directions
stay open. `PROOF-STATUS.adoc` marks ET-2 proven *for the L1 core
calculus*, under the core-vs-full-theory caveat that file already
carries.

**ET-14 (TEA erasure) is untouched and remains the headline open
problem**, gated on the owner's ET-16 / L0-lowering ADR.

## Merge notes

Per the base ruleset, **squash is the only merge that works** here
(rebase merges cannot be signed by GitHub bots), and the phantom
required `Dependabot` context means this will need `--admin`. Not merged
by me — that call is yours.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant