Skip to content

Commit d6ebf68

Browse files
hyperpolymathclaude
andcommitted
proof: Swarm A+B+C closures land — at-pre helpers Qed, 10 preservation LEFT branches closed
Brings together three pieces of the 2026-05-26 Lemma B campaign: 1. `step_preserves_type_at_pre` (Swarm A) — 5 remaining per-goal cases closed via explicit `1: {...}` blocks (S_StringConcat_Step2, S_App_Step2, S_Snd atomic, S_Case_Step, S_Copy). Now Qed. 2. `step_output_context_eq_at_pre` (Swarm B) — 11 remaining per-goal cases closed. Now Qed. 3. `preservation` — Swarm C oracle splice closes the LEFT (R = R') branch of every congruence case via `step_output_context_eq` (Qed): `assert Gmid = Gout by (eapply step_output_context_eq; …); subst` unifies the IH's existential output context with the sibling typing's input. `S_StringLen_Step` closes ENTIRELY as vacuous (`EBorrow`'s inner is `EVar` or a value — neither steps — pattern lifted from `S_Borrow_Step`). `S_StringConcat_Step1` collapsed from 3-way `step_R_change_shape` to 2-way `step_R_eq_or_touches_region` for consistency with the other 10 S_*_Step blocks; the MIDDLE (push) closure is folded into the touches_region RIGHT and will be re-distinguished by the C-lemma's structural recursion. Net: preservation drops from 12 → 11 admits. The remaining 11 are: - 10 touches_region RIGHT sub-cases (`HTR : touches_region` in scope), each blocked on region-env weakening for non-values (= Brief C, structural follow-up). - 1 `S_Region_Step` cross-case `T_Region_Active × T_Region` at `r = r1` ("inner step exits outer region from inside") — same shape inside `step_preserves_type_at_pre`'s original obstacle, now cleanly characterised in PRESERVATION-HANDOFF.md. Verified with `coqc 8.18.0` on a clean rebuild. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9cb24b4 commit d6ebf68

2 files changed

Lines changed: 670 additions & 94 deletions

File tree

formal/PRESERVATION-HANDOFF.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ open and what the canonical closure path is.
2626
| 2026-05-24 (late) | Lemma B 31/35 closed | Cluster A (β-reduction, 7) **FULLY CLOSED** via `subst_preserves_typing_strong` + `output_ctx_det`. Cluster C (region/compound-value, 6) **FULLY CLOSED** via inversion + `value_context_unchanged`. Cluster B (congruence) 9 of 18 closed via R-shape dispatch. |
2727
| 2026-05-26 | **1 + 1 + 12** | Empirical `coqc 8.18.0` re-verification: 1 admit in `step_preserves_type` (Semantics.v:4885), 1 admit in `step_output_context_eq` (Semantics.v:5963), 12 cascading goals in `preservation`. The two upstream admits are the SAME structural sub-case — S_Region_Step's `r = r1` "exited from inside" — mirrored across both lemmas. |
2828
| 2026-05-26 (eve) | **0 + 0 + 12** (Qed × 2) | **Path 3 (at-pre helper) lands.** Both upstream lemmas are now `Qed`. Introduced two NEW helper lemmas (`step_preserves_type_at_pre` and `step_output_context_eq_at_pre`) whose typings are at the SHARED pre-step env R. The S_Region_Step cross-case `T_Region_Active × T_Region` collapses to a contradiction (In r R vs ~In r R at same env) — sidestepping the original obstacle. Plug-in via `region_env_perm_typing` + `remove_first_then_cons_membership_eq` (existing, Qed). The 12 cascading goals in `preservation` remain — they're a SEPARATE structural problem, not the shared admit. |
29+
| 2026-05-26 (late eve) | **Qed × 4 + 11** | **Swarm A + B + C complete.** `step_preserves_type_at_pre` and `step_output_context_eq_at_pre` are now Qed (Swarm A + B per-goal closures landed). Swarm C oracle splice closes all 10 congruence LEFT branches in `preservation` via `step_output_context_eq` (Qed) — `assert Gmid = Gout by (eapply step_output_context_eq; …); subst` unifies the IH's existential output context with the sibling's Gmid. `S_StringLen_Step` closes ENTIRELY as vacuous (`EBorrow`'s inner is `EVar` or value, neither steps — pattern lifted from `S_Borrow_Step` elsewhere in this proof). 11 admits remain in `preservation`: 10 RIGHT-only sub-cases (`HTR : touches_region` in scope) + 1 `S_Region_Step` (special). All 10 RIGHT cases share the same shape and block on the same region-env weakening lemma for non-values (= Brief C, structural follow-up). |
2930

3031
> **Path 3 (landed 2026-05-26 eve):** The Option 2 plan (structural
3132
> recursion deriving `expr_free_of_region`) was **blocked** by the
@@ -503,6 +504,108 @@ proves. If the inductive structure of Lemma B turns out to need
503504
preservation as a sub-lemma, the closure path needs revision.
504505
Watch for this when attacking the first Cluster B case.
505506

507+
## Open: region-env weakening for non-values (2026-05-26)
508+
509+
After `step_preserves_type` and `step_output_context_eq` reached Qed
510+
(via the at-pre helper pattern, Path 3 above), preservation's 12
511+
remaining admits split into two flavours:
512+
513+
| Sub-case | Count | Blocker |
514+
|----------|------:|---------|
515+
| Congruence RIGHT (touches_region) | 11 | r-shrunk env, sibling might reference r |
516+
| `S_Region_Step` + `T_Region_Active` × `T_Region` (r=r1) | 1 | same shape inside `step_preserves_type_at_pre` |
517+
518+
The 11 RIGHT-branch admits each have shape:
519+
520+
> `Hstep : (mu, R, e1) -->> (mu', R', e1')`,
521+
> `HTR : touches_region e1`,
522+
> `H1 : R; G |- e1 : T1 -| Gmid`,
523+
> `H2 : R; <ctx> |- e2 : T2 -| <ctx'>` (the unchanged sibling),
524+
> `IH : ... → exists G_out, R'; G |- e1' : T1 -| G_out`
525+
>
526+
> `exists G_out, R'; G |- COMPOUND e1' e2 : ... -| G_out`
527+
528+
The IH gives the stepped child at `R'`. The sibling `e2` is still
529+
typed at `R`. To reconstruct `COMPOUND e1' e2` at `R'`, we need
530+
`R'; <ctx> |- e2 : T2 -| <ctx'>` — i.e. a *non-value* region-env
531+
weakening lemma carrying e2 from `R` to `R'`.
532+
533+
Three candidate formulations were explored in 2026-05-26 sessions:
534+
535+
### III-a — Permutation-aware variant (PROVABLE, LANDED, CLOSES 0/12)
536+
537+
**Statement**:
538+
```coq
539+
Lemma region_shrink_preserves_typing_dup :
540+
forall R G e T G' r,
541+
R; G |- e : T -| G' ->
542+
In r (remove_first r R) ->
543+
(remove_first r R); G |- e : T -| G'.
544+
```
545+
546+
**Proof**: pure transport via `region_env_perm_typing` — when
547+
`In r (remove_first r R)`, the membership of every region is
548+
preserved. ~15 LOC. Now Qed at `Semantics.v:3332`.
549+
550+
**Why it doesn't close any admit**: the duplicate-r hypothesis
551+
`In r (remove_first r R)` is never available in the touches_region
552+
RIGHT branches. `S_Region_Exit`'s premise (`In r R`) only guarantees
553+
single membership; the dual `In r (remove_first r R)` would require
554+
multi-occurrence, which a well-typed initial program never
555+
produces (`T_Region`'s `~In r R` premise prevents same-name
556+
shadowing throughout reachable configurations).
557+
558+
Lands as adjunct infrastructure: completes the case split alongside
559+
`region_shrink_preserves_typing` and documents the explored
560+
formulation.
561+
562+
### III-b — `no_leaks` invariant as oracle (NOT VIABLE)
563+
564+
`no_leaks` (line 374) proves only a memory-side fact:
565+
`mem_read mu' l = Some (CString r s) -> False`. It says nothing
566+
about whether `e'` is syntactically free of `r`. The bridge that
567+
would make it useful — `step_exit_implies_free_of_exited_region`
568+
is **false** for congruence cases (the surviving sibling's
569+
references to r break the freedom claim, as documented above at
570+
"step_exit_implies_free_of_exited_region would be false").
571+
Re-engineering `no_leaks` to produce expression-side freedom would
572+
require strengthening its conclusion from "memory free of r" to
573+
"resulting expression syntactically free of r" — a different
574+
judgement entirely, equivalent in effort to the auxiliary lemma
575+
itself. III-b collapses to III-a / Option 2.
576+
577+
### III-c — Restated preservation with membership-equivalence (WRONG AXIS)
578+
579+
Weakening preservation's conclusion to `exists R'', (forall r, In r R''
580+
<-> In r R') /\ R''; G |- e' : T -| G'` does not help: 11 of the 12
581+
open goals are blocked on **G-context** Skolem alignment (already
582+
solved by the Swarm-C `step_output_context_eq` splice), and the
583+
12th wants genuine *weakening* (`r :: R'`), not membership-
584+
equivalence. III-c diagnoses the wrong axis.
585+
586+
### Conclusion
587+
588+
The 12 admits do **not** dissolve under a clean lemma-level fix.
589+
They require one of:
590+
591+
1. **Mutual induction** with `preservation` and `step_preserves_type`
592+
simultaneously (Option 1 above — the standard textbook approach
593+
for region calculi, but a significant restructuring).
594+
2. **Inversion-on-Hstep structural recursion** (~150 LOC, Option 2
595+
above) — orthogonal to the current case split; closes the single
596+
`step_preserves_type_at_pre` admit at the source, which cascades
597+
to the corresponding preservation admit.
598+
3. **Type-system change**: add a sibling-region-disjointness side
599+
condition to `T_Let`, `T_App`, etc. — ensures every well-typed
600+
compound rules out the bad configuration where exit-able r is
601+
shared with a sibling. Requires re-proving every existing lemma
602+
under the new typing rule.
603+
604+
Recommend Option 2 (~150 LOC, scope-isolated) over Option 1
605+
(refactor entire proof). Type-system change (Option 3) is the
606+
"correct" fix for the underlying concrete-name encoding gap, but
607+
the cost (re-prove every lemma) is high.
608+
506609
## Unwind checklist (when finally closed)
507610

508611
1. Replace `Admitted.` with `Qed.`

0 commit comments

Comments
 (0)