Skip to content

Commit a54ecb7

Browse files
proof(L1.G): convert Axiom region_liveness_at_split_l1 to Lemma with 1 narrow admit (#181)
## Summary Adaptation of design-branch PR #178 to main's m-indexed `has_type_l1` (per #176). Replaces the opaque universal `Axiom region_liveness_at_split_l1` with a structurally-proved `Lemma … Admitted.` that closes 28 of 29 inductive cases concretely, leaving exactly 1 admit at the documented counterexample sub-case (T_Region_Active_L1 with binder = rv). ## Structure 1. **`region_liveness_at_split_l1_gen`** — generalised over the modality parameter `m`. Induction handles all 29 constructors including the mode-split `T_Lam_L1_Linear/Affine`, `T_Case_L1_Linear/Affine`, `T_If_L1_Linear/Affine`. - R-unchanged cases (11) auto-discharge via `try assumption`. - Compound cases (16) route IH chains. - `T_Region_L1` (fresh binder) closes via `remove_first_L1_count_other` (~In r R ∧ In rv R gives r ≠ rv). - `T_Region_Active_L1` splits on `r =? rv`: - `r ≠ rv`: same `remove_first_L1_count_other` argument. - `r = rv`: **GENUINELY FALSE — admit** with documented counterexample. 2. **`region_liveness_at_split_l1`** — Linear-specialised wrapper matching the original Axiom's signature for existing call sites in `subst_typing_gen_l1`. One-line proof by `eapply` on `_gen`. ## What this is and isn't **Is**: a proof-debt **transparency** improvement. 28 cases now have concrete witnesses; the residual obstacle is one narrowly-defined sub-case with a source-level counterexample. **Isn't**: a soundness improvement. The lemma's statement is universal `forall e`, still false in the residual sub-case, still accepted by `Admitted.` the same way `Axiom` was. Counterexample: ``` ERegion rv (EI32 5) : TBase TI32 -| [] at R = [rv] ``` The rule pops the only `rv` from `R_body`; `In rv R = True` but `In rv R' = False`. ## Closure paths forward (in-file) - **(i)** Restate with a `no_region_active_pop_of rv e` side condition and discharge at the 9 call sites in `subst_typing_gen_l1` (smallest step). - **(ii)** Multi-set `region_env` (substantial L1 redesign). - **(iii)** Weaker contextual signature. ## Verification - 0 Axiom declarations in `formal/Semantics_L1.v` (down from 1) - Full project rebuild: 9 .v files clean - `Counterexample.v` still Qed (regression test for the L1 design counterexample) - `Print Assumptions subst_preserves_typing_l1` still mentions `region_liveness_at_split_l1` (now as opaque Admitted-Lemma, not Axiom — same logical state) ## Test plan - [x] `coqc 8.18.0` builds cleanly - [x] Clean full-project rebuild passes — 9 .v files - [x] 0 `Axiom` declarations in `Semantics_L1.v` - [ ] CI green Refs PR #178 (design-branch original), PR #176 (L2 hybrid + m-indexing). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent c01f0fa commit a54ecb7

1 file changed

Lines changed: 112 additions & 4 deletions

File tree

formal/Semantics_L1.v

Lines changed: 112 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -602,14 +602,122 @@ Proof. intros. apply T_Loc_L1. assumption. Qed.
602602
the bound variable inside its body, but the body's typing flag
603603
transition is observable via [output_shape_at_l1] in the caller).
604604
605-
See header above for the three closure approaches. Tracked as L1
606-
follow-up work; isolating it here lets [subst_typing_gen_l1] reach
607-
[Qed.] without further axioms. *)
608-
Axiom region_liveness_at_split_l1 :
605+
See header above for the three closure approaches.
606+
607+
=== 2026-05-27 partial discharge: Axiom → Lemma with 1 narrow admit ===
608+
609+
[Axiom] is replaced with [Lemma .. Admitted.] below. The proof
610+
body structurally encodes the case-by-case analysis the header
611+
describes, generalised over the modality parameter [m] that
612+
[has_type_l1] now carries (per PR #176's L2 hybrid):
613+
614+
- 25 base + compound cases close mechanically (R unchanged or
615+
threaded through sub-derivations via IH). This includes the
616+
mode-split T_Lam_L1_Linear / T_Lam_L1_Affine (both R-unchanged),
617+
T_Case_L1_Linear / T_Case_L1_Affine, T_If_L1_Linear /
618+
T_If_L1_Affine.
619+
- T_Region_L1 (fresh binder, modality-polymorphic) closes via
620+
[remove_first_L1_count_other]: [~ In r R ∧ In rv R] gives
621+
[r ≠ rv], so the pop preserves rv.
622+
- T_Region_Active_L1 (re-entry binder, modality-polymorphic):
623+
* Sub-case [r ≠ rv]: same [remove_first_L1_count_other] argument.
624+
* Sub-case [r = rv]: the GENUINELY-FALSE case. One [admit] sits
625+
here, with the source-level counterexample
626+
[ERegion rv (EI32 5)] at [R = [rv]]. The rule pops the only
627+
[rv] from [R_body]; [In rv R = True] but [In rv R' = False].
628+
629+
This converts an opaque universal Axiom into a Lemma with one
630+
explicitly-narrow admit. The remaining admit is a structural
631+
obligation tied to a documented counterexample, addressable by
632+
any of the three closure paths (i)/(ii)/(iii) above. Not a
633+
soundness improvement (the lemma's statement is still false in
634+
the one residual sub-case); a proof-debt transparency
635+
improvement.
636+
637+
Refs PR #178 (design-branch original; superseded by main's
638+
L2-hybrid #176). *)
639+
640+
(** Generalised over the modality parameter [m]. The wrapper below
641+
matches the original Linear-only Axiom signature for the
642+
existing call sites in [subst_typing_gen_l1]. *)
643+
Lemma region_liveness_at_split_l1_gen :
644+
forall m R G e T R' G' rv,
645+
has_type_l1 m R G e T R' G' ->
646+
In rv R ->
647+
In rv R'.
648+
Proof.
649+
intros m R G e T R' G' rv Ht.
650+
induction Ht; intros Hin; try assumption.
651+
(* Compound cases — thread rv through sub-derivations via IH. *)
652+
- (* T_StringConcat_L1: R -> R1 -> R2 *)
653+
apply IHHt2. apply IHHt1. assumption.
654+
- (* T_StringLen_L1 *)
655+
apply IHHt. assumption.
656+
- (* T_Let_L1 *)
657+
apply IHHt2. apply IHHt1. assumption.
658+
- (* T_LetLin_L1 *)
659+
apply IHHt2. apply IHHt1. assumption.
660+
- (* T_App_L1 *)
661+
apply IHHt2. apply IHHt1. assumption.
662+
- (* T_Pair_L1 *)
663+
apply IHHt2. apply IHHt1. assumption.
664+
- (* T_Fst_L1 *)
665+
apply IHHt. assumption.
666+
- (* T_Snd_L1 *)
667+
apply IHHt. assumption.
668+
- (* T_Inl_L1 *)
669+
apply IHHt. assumption.
670+
- (* T_Inr_L1 *)
671+
apply IHHt. assumption.
672+
- (* T_Case_L1_Linear: R -> R1 -> R_final *)
673+
apply IHHt2. apply IHHt1. assumption.
674+
- (* T_Case_L1_Affine: same shape *)
675+
apply IHHt2. apply IHHt1. assumption.
676+
- (* T_If_L1_Linear: R -> R1 -> R2 *)
677+
apply IHHt2. apply IHHt1. assumption.
678+
- (* T_If_L1_Affine *)
679+
apply IHHt2. apply IHHt1. assumption.
680+
- (* T_Region_L1 (fresh): ~In r R + In rv R gives r ≠ rv;
681+
remove_first_L1 preserves rv. *)
682+
assert (Hne : r <> rv).
683+
{ intro Heq. subst rv. apply H. exact Hin. }
684+
assert (Hin_body_in : In rv (r :: R)) by (right; exact Hin).
685+
pose proof (IHHt Hin_body_in) as HinRbody.
686+
apply (count_occ_In string_dec).
687+
pose proof (remove_first_L1_count_other r rv R_body Hne) as Heq.
688+
unfold cnt in Heq. rewrite Heq.
689+
apply (count_occ_In string_dec). exact HinRbody.
690+
- (* T_Region_Active_L1: two sub-cases r=rv / r ≠ rv *)
691+
destruct (string_dec r rv) as [Heq|Hne].
692+
+ (* r = rv: GENUINELY FALSE. Counterexample at the source level:
693+
ERegion rv (EI32 5) at R = [rv] — body R_body = [rv], pop
694+
yields [], so In rv R = True but In rv R' = False. *)
695+
admit.
696+
+ (* r ≠ rv: same shape as T_Region_L1. *)
697+
pose proof (IHHt Hin) as HinRbody.
698+
apply (count_occ_In string_dec).
699+
pose proof (remove_first_L1_count_other r rv R_body Hne) as Heq.
700+
unfold cnt in Heq. rewrite Heq.
701+
apply (count_occ_In string_dec). exact HinRbody.
702+
(* T_Borrow_L1, T_Borrow_Val_L1: R unchanged, auto-discharged by
703+
[try assumption] above. *)
704+
- (* T_Drop_L1 *)
705+
apply IHHt. assumption.
706+
- (* T_Copy_L1 *)
707+
apply IHHt. assumption.
708+
Admitted.
709+
710+
(** Linear-specialised wrapper matching the original Axiom signature
711+
for the call sites in [subst_typing_gen_l1]. *)
712+
Lemma region_liveness_at_split_l1 :
609713
forall R G e T R' G' rv,
610714
R; G |=L1 e : T -| R'; G' ->
611715
In rv R ->
612716
In rv R'.
717+
Proof.
718+
intros R G e T R' G' rv Ht.
719+
eapply region_liveness_at_split_l1_gen. exact Ht.
720+
Qed.
613721

614722
(** Generalized substitution: at depth [k] for a linear value [v].
615723
Mirrors legacy [subst_typing_gen]. The only L1-specific gap is the

0 commit comments

Comments
 (0)