88 *** ***
99 *** This is the post-counterexample L1 redesign. Extend HERE. ***
1010 *** ***
11- *** 9 `Admitted` lemmas remaining are L2-INTEGRATION DEBT (bullet ***
12- *** structure for the 3 new Affine-only constructors ***
13- *** T_Lam_L1_Affine, T_Case_L1_Affine, T_If_L1_Affine added by ***
14- *** the L2-hybrid landing in PRs #176 + #177). ***
11+ *** 4 `Admitted` lemmas remain (down from 7 mid-chain, 9 pre- ***
12+ *** bullet-restoration). Three pure bullet-structure regressions ***
13+ *** closed 2026-05-27 (typing_preserves_bindings_l1, ***
14+ *** unrestricted_flag_unchanged_l1, shift_typing_gen_l1 via ***
15+ *** shift_typing_gen_l1_m + wrapper). typing_preserves_length_l1 ***
16+ *** generalised to m-polymorphic. ***
17+ *** ***
18+ *** Residual admits (L2-β follow-up): ***
19+ *** 1. region_shrink_preserves_typing_l1_gen — list-vs-multiset ***
20+ *** structural mismatch in T_Region_Active_L1 shadowed case ***
21+ *** 2. region_liveness_at_split_l1_gen — 1 narrow admit in the ***
22+ *** T_Region_Active_L1 [r = rv] sub-case (genuinely false ***
23+ *** per documented counterexample ERegion rv (EI32 5)) ***
24+ *** 3. subst_typing_gen_l1 — needs modality-polymorphic ***
25+ *** generalisation (next L2-β PR) ***
26+ *** 4. preservation_l1 — depends on (3) + lambda-rigidity gap ***
1527 *** ***
1628 *** DO NOT close them by: ***
1729 *** - introducing new `Axiom` declarations ***
@@ -403,29 +415,79 @@ Qed.
403415 These mirror analogous lemmas in [Semantics.v] for the legacy
404416 judgment but are stated and proved for [has_type_l1]. *)
405417
406- (** Length preserved by every typing rule. *)
418+ (** Length preserved by every typing rule.
419+
420+ L2-β: generalised to modality-polymorphic [has_type_l1 m]. The
421+ length invariant is modality-independent (every constructor
422+ threads ctx length identically). Linear-specific callers
423+ continue to work via instantiation. *)
407424Lemma typing_preserves_length_l1 :
408- forall R G e T R' G',
409- R; G |=L1 e : T -| R' ; G' ->
425+ forall m R G e T R' G',
426+ has_type_l1 m R G e T R' G' ->
410427 length G' = length G.
411428Proof .
412- intros R G e T R' G' H.
429+ intros m R G e T R' G' H.
413430 induction H; simpl in *; try reflexivity; try lia;
414431 try (rewrite ctx_mark_used_length; reflexivity).
415432Qed .
416433
417- (** Output-context lookup preserves type at the same index. *)
434+ (** Output-context lookup preserves type at the same index.
435+
436+ L2-β restoration 2026-05-27: body ported from commit 56f592f.
437+ Three new Affine-only constructors (T_Lam_L1_Affine,
438+ T_Case_L1_Affine, T_If_L1_Affine) are auto-discharged because
439+ induction on [|=L1] (= [has_type_l1 Linear]) produces no live
440+ subgoals for them — their typing-rule conclusion has the wrong
441+ modality index. The bullet structure therefore covers only the
442+ 7 mode-polymorphic compound cases. *)
418443Lemma typing_preserves_bindings_l1 :
419444 forall R G e T R' G',
420445 R; G |=L1 e : T -| R' ; G' ->
421446 forall i T0 u0,
422447 ctx_lookup G' i = Some (T0, u0) ->
423448 exists u1, ctx_lookup G i = Some (T0, u1).
424449Proof .
425- (* L2 regression: induction case ordering shifted by new constructors. Admitted; restoration is L2-β. *)
426- Admitted .
450+ intros R G e T R' G' Htype.
451+ induction Htype; intros idx Ty uf Hlk; simpl in *;
452+ try (eexists; exact Hlk);
453+ try (eapply IHHtype; exact Hlk).
454+ - (* T_Var_Lin_L1: G' = ctx_mark_used G i *)
455+ eapply ctx_mark_used_lookup_type. exact Hlk.
456+ - (* T_StringConcat_L1 *)
457+ destruct (IHHtype2 _ _ _ Hlk) as [u_mid Hu_mid].
458+ eapply IHHtype1. exact Hu_mid.
459+ - (* T_Let_L1 *)
460+ destruct (IHHtype2 (S idx) Ty uf) as [u_mid Hu_mid]; [exact Hlk|].
461+ eapply IHHtype1. exact Hu_mid.
462+ - (* T_LetLin_L1 *)
463+ destruct (IHHtype2 (S idx) Ty uf) as [u_mid Hu_mid]; [exact Hlk|].
464+ eapply IHHtype1. exact Hu_mid.
465+ - (* T_App_L1 *)
466+ destruct (IHHtype2 _ _ _ Hlk) as [u_mid Hu_mid].
467+ eapply IHHtype1. exact Hu_mid.
468+ - (* T_Pair_L1 *)
469+ destruct (IHHtype2 _ _ _ Hlk) as [u_mid Hu_mid].
470+ eapply IHHtype1. exact Hu_mid.
471+ - (* T_Case_L1_Linear *)
472+ destruct (IHHtype2 (S idx) Ty uf) as [u_mid Hu_mid]; [exact Hlk|].
473+ eapply IHHtype1. exact Hu_mid.
474+ - (* T_Case_L1_Affine: same shape — branch 2 ignored; branch 1 carries through *)
475+ destruct (IHHtype2 (S idx) Ty uf) as [u_mid Hu_mid]; [exact Hlk|].
476+ eapply IHHtype1. exact Hu_mid.
477+ - (* T_If_L1_Linear *)
478+ destruct (IHHtype2 _ _ _ Hlk) as [u_mid Hu_mid].
479+ eapply IHHtype1. exact Hu_mid.
480+ - (* T_If_L1_Affine *)
481+ destruct (IHHtype2 _ _ _ Hlk) as [u_mid Hu_mid].
482+ eapply IHHtype1. exact Hu_mid.
483+ Qed .
484+
485+ (** Unrestricted (non-linear) bindings are unchanged through typing.
427486
428- (** Unrestricted (non-linear) bindings are unchanged through typing. *)
487+ L2-β restoration 2026-05-27: body ported from commit 56f592f with
488+ new bullets for T_Case_L1_Affine + T_If_L1_Affine. T_Lam_L1_Affine
489+ auto-discharges through [try exact Hlk] (R/G unchanged at the
490+ rule's conclusion). *)
429491Lemma unrestricted_flag_unchanged_l1 :
430492 forall R G e T R' G',
431493 R; G |=L1 e : T -| R' ; G' ->
@@ -434,8 +496,46 @@ Lemma unrestricted_flag_unchanged_l1 :
434496 ctx_lookup G j = Some (T0, u) ->
435497 ctx_lookup G' j = Some (T0, u).
436498Proof .
437- (* L2 regression: induction case ordering shifted. L2-β follow-up. *)
438- Admitted .
499+ intros R G e T R' G' Htype.
500+ induction Htype; intros idx T0 u0 Hnlin Hlk; simpl in *;
501+ try exact Hlk;
502+ try (eapply IHHtype; eassumption).
503+ - (* T_Var_Lin_L1 *)
504+ destruct (Nat.eq_dec i idx) as [->|Hne].
505+ + unfold ctx_lookup in *. rewrite H in Hlk. injection Hlk as <- <-.
506+ rewrite Hnlin in H0. discriminate.
507+ + rewrite ctx_mark_used_lookup_other by exact Hne. exact Hlk.
508+ - (* T_StringConcat_L1 *)
509+ eapply IHHtype2; [exact Hnlin|]. eapply IHHtype1; eassumption.
510+ - (* T_Let_L1 *)
511+ apply (IHHtype1 idx T0 u0 Hnlin) in Hlk.
512+ assert (HlkS: ctx_lookup (ctx_extend G' T1) (S idx) = Some (T0, u0)) by exact Hlk.
513+ apply (IHHtype2 (S idx) T0 u0 Hnlin) in HlkS.
514+ unfold ctx_lookup, ctx_extend in HlkS. simpl in HlkS. exact HlkS.
515+ - (* T_LetLin_L1 *)
516+ apply (IHHtype1 idx T0 u0 Hnlin) in Hlk.
517+ assert (HlkS: ctx_lookup (ctx_extend G' T1) (S idx) = Some (T0, u0)) by exact Hlk.
518+ apply (IHHtype2 (S idx) T0 u0 Hnlin) in HlkS.
519+ unfold ctx_lookup, ctx_extend in HlkS. simpl in HlkS. exact HlkS.
520+ - (* T_App_L1 *)
521+ eapply IHHtype2; [exact Hnlin|]. eapply IHHtype1; eassumption.
522+ - (* T_Pair_L1 *)
523+ eapply IHHtype2; [exact Hnlin|]. eapply IHHtype1; eassumption.
524+ - (* T_Case_L1_Linear *)
525+ apply (IHHtype1 idx T0 u0 Hnlin) in Hlk.
526+ assert (HlkS: ctx_lookup (ctx_extend G' T1) (S idx) = Some (T0, u0)) by exact Hlk.
527+ apply (IHHtype2 (S idx) T0 u0 Hnlin) in HlkS.
528+ unfold ctx_lookup, ctx_extend in HlkS. simpl in HlkS. exact HlkS.
529+ - (* T_Case_L1_Affine — same shape *)
530+ apply (IHHtype1 idx T0 u0 Hnlin) in Hlk.
531+ assert (HlkS: ctx_lookup (ctx_extend G' T1) (S idx) = Some (T0, u0)) by exact Hlk.
532+ apply (IHHtype2 (S idx) T0 u0 Hnlin) in HlkS.
533+ unfold ctx_lookup, ctx_extend in HlkS. simpl in HlkS. exact HlkS.
534+ - (* T_If_L1_Linear *)
535+ eapply IHHtype2; [exact Hnlin|]. eapply IHHtype1; eassumption.
536+ - (* T_If_L1_Affine *)
537+ eapply IHHtype2; [exact Hnlin|]. eapply IHHtype1; eassumption.
538+ Qed .
439539
440540(** If a false-flag binding becomes true, the type must be linear. *)
441541Lemma flag_false_to_true_implies_linear_l1 :
@@ -460,7 +560,7 @@ Lemma output_shape_at_l1 :
460560 exists u_out, nth_error Gout k = Some (T1, u_out).
461561Proof .
462562 intros R Gin e T R' Gout k T1 u_in Htype Hin.
463- assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ Htype).
563+ assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ _ Htype).
464564 assert (Hlt: k < length Gout).
465565 { rewrite Hlen. apply nth_error_Some. congruence. }
466566 destruct (nth_error Gout k) as [[T1' u']|] eqn:E.
@@ -534,16 +634,143 @@ Qed.
534634
535635(** Shift typing for L1: shifting [e] up by 1 at cutoff [k] in the
536636 context corresponds to inserting a fresh (T_new, false) at position
537- [k] in both input and output. R is unchanged at every rule. *)
637+ [k] in both input and output. R is unchanged at every rule.
638+
639+ L2-β restoration 2026-05-27: generalised to modality-polymorphic
640+ [has_type_l1 m] mirroring [region_liveness_at_split_l1_gen]'s
641+ shape. The Linear-only wrapper [shift_typing_gen_l1] preserves
642+ the original signature for callers. Body ported from commit
643+ 56f592f with new bullets for T_Lam_L1_Affine, T_Case_L1_Affine,
644+ T_If_L1_Affine — each Affine case mirrors its Linear counterpart
645+ since R and `insert_at` threading are modality-independent. *)
646+ Lemma shift_typing_gen_l1_m :
647+ forall m R G e T R' G',
648+ has_type_l1 m R G e T R' G' ->
649+ forall k T_new,
650+ k <= length G ->
651+ has_type_l1 m R (insert_at k (T_new, false) G) (shift k 1 e) T R' (insert_at k (T_new, false) G').
652+ Proof .
653+ intros m R G e T R' G' Htype.
654+ induction Htype; intros k T_new Hk; simpl.
655+ - apply T_Unit_L1.
656+ - apply T_Bool_L1.
657+ - apply T_I32_L1.
658+ (* T_Var_Lin_L1 *)
659+ - destruct (Nat.leb_spec k i).
660+ + rewrite (insert_at_ctx_mark_used_ge G k i (T_new, false) H1 Hk).
661+ replace (i + 1) with (S i) by lia.
662+ eapply T_Var_Lin_L1.
663+ * unfold ctx_lookup. rewrite nth_error_insert_at_gt by (try assumption; try lia).
664+ unfold ctx_lookup in H. exact H.
665+ * exact H0.
666+ + rewrite (insert_at_ctx_mark_used_lt G k i (T_new, false) H1 Hk).
667+ eapply T_Var_Lin_L1.
668+ * unfold ctx_lookup. rewrite nth_error_insert_at_lt by (try assumption; try lia).
669+ unfold ctx_lookup in H. exact H.
670+ * exact H0.
671+ (* T_Var_Unr_L1 *)
672+ - destruct (Nat.leb_spec k i).
673+ + replace (i + 1) with (S i) by lia. eapply T_Var_Unr_L1.
674+ * unfold ctx_lookup. rewrite nth_error_insert_at_gt by (try assumption; try lia).
675+ unfold ctx_lookup in H. exact H.
676+ * exact H0.
677+ + eapply T_Var_Unr_L1.
678+ * unfold ctx_lookup. rewrite nth_error_insert_at_lt by (try assumption; try lia).
679+ unfold ctx_lookup in H. exact H.
680+ * exact H0.
681+ (* T_Loc_L1 *)
682+ - apply T_Loc_L1. exact H.
683+ (* T_StringNew_L1 *)
684+ - apply T_StringNew_L1. exact H.
685+ (* T_StringConcat_L1 *)
686+ - eapply T_StringConcat_L1; [apply IHHtype1; assumption|].
687+ apply IHHtype2. assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ _ Htype1). lia.
688+ (* T_StringLen_L1 *)
689+ - eapply T_StringLen_L1. apply IHHtype. assumption.
690+ (* T_Let_L1 *)
691+ - assert (IH1 := IHHtype1 k T_new Hk).
692+ assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ _ Htype1).
693+ assert (IH2 := IHHtype2 (S k) T_new ltac:(simpl; lia)).
694+ simpl in IH2. eapply T_Let_L1; eassumption.
695+ (* T_LetLin_L1 *)
696+ - assert (IH1 := IHHtype1 k T_new Hk).
697+ assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ _ Htype1).
698+ assert (IH2 := IHHtype2 (S k) T_new ltac:(simpl; lia)).
699+ simpl in IH2. eapply T_LetLin_L1; eassumption.
700+ (* T_Lam_L1_Linear *)
701+ - assert (IH := IHHtype (S k) T_new ltac:(simpl; lia)).
702+ simpl in IH. eapply T_Lam_L1_Linear. exact IH.
703+ (* T_Lam_L1_Affine *)
704+ - assert (IH := IHHtype (S k) T_new ltac:(simpl; lia)).
705+ simpl in IH. eapply T_Lam_L1_Affine. exact IH.
706+ (* T_App_L1 *)
707+ - eapply T_App_L1; [apply IHHtype1; assumption|].
708+ apply IHHtype2. assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ _ Htype1). lia.
709+ (* T_Pair_L1 *)
710+ - eapply T_Pair_L1; [apply IHHtype1; assumption|].
711+ apply IHHtype2. assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ _ Htype1). lia.
712+ (* T_Fst_L1 *)
713+ - eapply T_Fst_L1; [apply IHHtype; assumption | assumption].
714+ (* T_Snd_L1 *)
715+ - eapply T_Snd_L1; [apply IHHtype; assumption | assumption].
716+ (* T_Inl_L1 *)
717+ - eapply T_Inl_L1. apply IHHtype. assumption.
718+ (* T_Inr_L1 *)
719+ - eapply T_Inr_L1. apply IHHtype. assumption.
720+ (* T_Case_L1_Linear *)
721+ - assert (IH1 := IHHtype1 k T_new Hk).
722+ assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ _ Htype1).
723+ assert (IH2 := IHHtype2 (S k) T_new ltac:(simpl; lia)).
724+ assert (IH3 := IHHtype3 (S k) T_new ltac:(simpl; lia)).
725+ simpl in IH2, IH3. eapply T_Case_L1_Linear; eassumption.
726+ (* T_Case_L1_Affine *)
727+ - assert (IH1 := IHHtype1 k T_new Hk).
728+ assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ _ Htype1).
729+ assert (IH2 := IHHtype2 (S k) T_new ltac:(simpl; lia)).
730+ assert (IH3 := IHHtype3 (S k) T_new ltac:(simpl; lia)).
731+ simpl in IH2, IH3. eapply T_Case_L1_Affine; eassumption.
732+ (* T_If_L1_Linear *)
733+ - eapply T_If_L1_Linear; [apply IHHtype1; assumption| |].
734+ + apply IHHtype2. assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ _ Htype1). lia.
735+ + apply IHHtype3. assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ _ Htype1). lia.
736+ (* T_If_L1_Affine *)
737+ - eapply T_If_L1_Affine; [apply IHHtype1; assumption| |].
738+ + apply IHHtype2. assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ _ Htype1). lia.
739+ + apply IHHtype3. assert (Hlen := typing_preserves_length_l1 _ _ _ _ _ _ _ Htype1). lia.
740+ (* T_Region_L1 *)
741+ - eapply T_Region_L1; [exact H | exact H0 | exact H1 |]. apply IHHtype. assumption.
742+ (* T_Region_Active_L1 *)
743+ - eapply T_Region_Active_L1; [exact H | exact H0 | exact H1 |]. apply IHHtype. assumption.
744+ (* T_Borrow_L1 *)
745+ - destruct (Nat.leb_spec k i).
746+ + replace (i + 1) with (S i) by lia. eapply T_Borrow_L1.
747+ unfold ctx_lookup. rewrite nth_error_insert_at_gt by (try assumption; try lia).
748+ unfold ctx_lookup in H. exact H.
749+ + eapply T_Borrow_L1. unfold ctx_lookup.
750+ rewrite nth_error_insert_at_lt by (try assumption; try lia).
751+ unfold ctx_lookup in H. exact H.
752+ (* T_Borrow_Val_L1 *)
753+ - eapply T_Borrow_Val_L1.
754+ + apply shift_preserves_value. exact H.
755+ + apply IHHtype. assumption.
756+ (* T_Drop_L1 *)
757+ - eapply T_Drop_L1; [exact H |]. apply IHHtype. assumption.
758+ (* T_Copy_L1 *)
759+ - eapply T_Copy_L1; [exact H |]. apply IHHtype. assumption.
760+ Qed .
761+
762+ (** Linear-specialised wrapper preserving the original lemma signature
763+ used by [preservation_l1] (Linear case). *)
538764Lemma shift_typing_gen_l1 :
539765 forall R G e T R' G',
540766 R; G |=L1 e : T -| R' ; G' ->
541767 forall k T_new,
542768 k <= length G ->
543769 R; insert_at k (T_new, false) G |=L1 shift k 1 e : T -| R'; insert_at k (T_new, false) G'.
544770Proof .
545- (* L2 regression: induction case ordering shifted. L2-β follow-up. *)
546- Admitted .
771+ intros R G e T R' G' Htype k T_new Hk.
772+ eapply shift_typing_gen_l1_m; eassumption.
773+ Qed .
547774
548775(** Sub-helper: linear values are locations [ELoc l r], and a location
549776 types at any region environment [R] with [In r R]. *)
@@ -748,8 +975,17 @@ Qed.
748975(** Generalized substitution: at depth [k] for a linear value [v].
749976 Mirrors legacy [subst_typing_gen]. The only L1-specific gap is the
750977 need to retype [v = ELoc l r] at the inner region environment of
751- compound rules. Closed via [region_liveness_at_use_l1] +
752- [loc_typing_l1]. *)
978+ compound rules. Closed via [region_liveness_at_split_l1] +
979+ [loc_retype_at_R_l1].
980+
981+ L2-β follow-up (post-2026-05-27): pure bullet restoration is
982+ insufficient — the lemma's goal mentions a specific modality
983+ (Linear via [|=L1] notation), so [induction Htype] generalises
984+ that index, leaving the IHs and sub-cases at variable [m].
985+ Closure requires modality-polymorphic generalisation (mirror of
986+ [shift_typing_gen_l1_m]'s shape) with extra care for
987+ [T_Lam_L1_Affine]'s flexible body-output flag. Tracked as L2-β
988+ follow-up #2 — separate PR. *)
753989Lemma subst_typing_gen_l1 :
754990 forall R Gin e T R' Gout,
755991 R; Gin |=L1 e : T -| R'; Gout ->
@@ -762,7 +998,7 @@ Lemma subst_typing_gen_l1 :
762998 nth_error Gout k = Some (T1, u_out) ->
763999 R; remove_at k Gin |=L1 subst k v e : T -| R'; remove_at k Gout.
7641000Proof .
765- (* L2 regression: induction case ordering shifted. L2 -β follow-up. *)
1001+ (* L2-β follow-up #2: needs modality-polymorphic generalisation . *)
7661002Admitted .
7671003
7681004(** Substitution preserves the L1 typing — the version used by
0 commit comments