Skip to content

Commit a0acdbc

Browse files
proofs(P06): state step_pop_disjoint_from_type_l1 + partial proof (Admitted) (#280)
## Summary Closes **P06** from the comprehensive proof inventory (partial — "useful partial progress, not a stuck session"): STATES the `step_pop_disjoint_from_type_l1` auxiliary lemma referenced by `preservation_l1`'s S_StringConcat_Step2 case per `PRESERVATION-DESIGN.md §4.7` ("L1.G follow-up"). ```coq Lemma step_pop_disjoint_from_type_l1 : forall mu R e mu' R' e' m G T R_final G', (mu, R, e) -->> (mu', R', e') -> has_type_l1 m R G e T R_final G' -> forall r, In r (Typing.free_regions T) -> In r R -> In r R'. ``` The lemma is `Admitted` (overall marker) but with a *structured* proof body: the easy cases are Qed-closed, and the hard cases admit with one-line per-case comments mapping cleanly to follow-up issues (#240 / #241 / #242). `Print Assumptions step_pop_disjoint_from_type_l1.` is emitted at file-end to certify the dependency audit. ### Easy cases CLOSED Qed (no internal admit) - Atomic non-region step rules (R' = R) - S_Region_Enter (R' = r' :: R) - S_Region_Exit / Exit_Echo (typing-rule premise `~ In r' (free_regions T)` discriminates the popped region from `r0`) - Same-type congruences: S_StringConcat_Step1 / Step2 (with `value_R_G_preserving_l1` for Step2), S_App_Step1, S_Fst_Step / Snd_Step, S_Drop_Step (Echo path), S_Copy_Step - S_Borrow_Step (via `values_dont_step`) - **PARTIAL** closure on S_Pair_Step1 / Step2 / S_Inl_Step / S_Inr_Step: the IH-tractable half (Hfree in the matching component's free_regions) closes; the cross-component half admits. - **PARTIAL** closure on S_Region_Step: T_Region_Active_L1 / Active_L1_Echo sub-cases close (body at outer R); T_Region_L1 / L1_Echo sub-cases admit (body at r' :: R, step at R — MISMATCH). ### Hard cases ADMITTED (10 internal `admit.` lines) S_Let_Step, S_LetLin_Step, S_App_Step2, S_If_Step, S_Pair_Step1 (T2-only branch), S_Pair_Step2 (T1-only branch), S_Inl_Step (T2-only branch), S_Inr_Step (T1-only branch), S_Case_Step, S_Region_Step (T_Region_L1 / L1_Echo sub-cases). All ten ride the **same §4.8 lambda-rigidity / variable-typing soundness gap**: the inner step's typing-rule type `T_inner` is not necessarily related to outer `T_outer` by `free_regions` inclusion, so an inner step can pop a region in `free_regions T_outer` without violating any inner-typing side condition. Concrete blockers tracked at ephapax issues #240 / #241 / #242. ### Effect on `preservation_l1` `preservation_l1`'s `admit.` count is **UNCHANGED (1 → 1)**. Rationale: the lemma being itself `Admitted` means using it in the S_StringConcat_Step2 case would only *relay* the admit one level up — no net axiom-count improvement. The commit's value is: 1. The lemma statement crystallises the obligation in mechanised form. 2. The ~70%-Qed sub-proof covers the operationally trivial / structurally trivial cases. 3. The per-case `admit.` comments map cleanly to follow-up issues #240 / #241 / #242 (Phase 3b Stage 2 / 3 / 4). 4. The `preservation_l1` header comment is updated to reference the new lemma. The "if stuck" escape clause of the original P06 brief explicitly allows this path: > If the S_StringConcat_Step2 case turns out to require additional non-trivial lemmas you didn't expect, STOP after stating the lemma cleanly. Submit a commit that adds the lemma statement + a precise structured `Admitted.` body documenting the obstacles you found. That's what landed here. ## Owner-directive compliance - ✅ Modifies only `formal/Semantics_L1.v` (post-redesign). - ✅ DOES NOT TOUCH `Semantics.v` / `Typing.v` / `Counterexample.v` (sacrosanct legacy). - ✅ ZERO new `Axiom` declarations. - ✅ ZERO new admits in any CLOSED lemma; all 10 new admits are inside the explicitly-Admitted `step_pop_disjoint_from_type_l1`. - ✅ Per-case `admit.` comments specifically reference Phase 3b Stage 2 / 3 / 4 and ephapax issues #240 / #241 / #242. - ✅ GPG-signed commit (key `4A03639C…`). ## Build oracle `just -f formal/Justfile all` GREEN — 12/12 modules compile. `Print Assumptions step_pop_disjoint_from_type_l1.` is emitted at file end and shows the lemma as the single new admitted statement (no additional axioms beyond pre-existing main). ## Admit count audit ``` pre-PR (origin/main): 5 admits across the file (region_shrink_preserves_typing_l1_gen_m × 2, region_liveness_at_split_l1_gen × 1, inline at line ~2014 × 1, preservation_l1 × 1) post-PR (this branch): 15 admits across the file (pre-existing 5 unchanged + step_pop_disjoint_from_type_l1 × 10) ``` The 10 new admits are NOT scattered — they cluster inside the single new lemma, each tagged with a specific follow-up issue. ## Test plan - [x] `cd formal && rm -f build.mk && just all` GREEN locally (12/12 modules) - [x] `Print Assumptions step_pop_disjoint_from_type_l1.` emitted at file end - [x] No new `Axiom` declarations - [x] No modifications to legacy `Semantics.v` / `Typing.v` / `Counterexample.v` - [ ] CI `coq-build.yml` workflow GREEN (will verify on merge attempt) ## Follow-up Issue to file post-merge: "P06 follow-up: discharge step_pop_disjoint_from_type_l1's 10 internal admits as §4.8 path (3) lands". Will link from ephapax#240 / #241 / #242. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9520d23 commit a0acdbc

1 file changed

Lines changed: 344 additions & 1 deletion

File tree

formal/Semantics_L1.v

Lines changed: 344 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3090,7 +3090,13 @@ Qed.
30903090
- S_StringConcat_Step2: TString r type — the lift is sound
30913091
operationally (popped region ≠ TString r region by
30923092
[expr_free_of_region]) but requires a specialized
3093-
[step_pop_disjoint_from_type_l1] lemma not yet proved.
3093+
[step_pop_disjoint_from_type_l1] lemma. P06 (this commit)
3094+
STATES and partially proves that lemma; the EASY cases of
3095+
the lemma are Qed (atomic + S_Region_Exit / Exit_Echo +
3096+
same-type congruences). The HARD cases of the lemma (which
3097+
match the HARD cases of preservation_l1) remain admitted
3098+
and ride the same §4.8 lambda-rigidity / variable-typing
3099+
gap — see [step_pop_disjoint_from_type_l1]'s header.
30943100
30953101
- S_App_Step2 / S_Pair_Step2: arbitrary value types — exposes
30963102
a fundamental gap in T_Lam_L1_Linear's body-R-rigidity: the lambda
@@ -3117,6 +3123,319 @@ Qed.
31173123
[Admitted.] but the proof body documents exactly which sub-cases
31183124
remain and the structural reason for each. *)
31193125

3126+
(** ** P06 — [step_pop_disjoint_from_type_l1]
3127+
3128+
Auxiliary lemma for the S_StringConcat_Step2 case of
3129+
[preservation_l1]. Per [PRESERVATION-DESIGN.md §4.7]: the
3130+
operational [step] never pops a region that appears free in the
3131+
type of the stepping expression. Combined with [In r R] from a
3132+
[TString r] value's typing (via [linear_value_is_loc_l1] +
3133+
[T_Loc_L1]), this gives [In r R'] which is exactly what is
3134+
needed to retype the LHS value [v1] of [EStringConcat v1 e2] at
3135+
the post-step env [R'] via [loc_retype_at_R_l1] /
3136+
[loc_retype_at_R_l1_m].
3137+
3138+
**Status (P06, this commit).** STATED + partial proof landed
3139+
Qed for the EASY cases (atomic non-region rules, S_Region_Enter,
3140+
S_Region_Exit / Exit_Echo, R-preserving congruences, S_StringConcat
3141+
congruences, S_Fst/Snd/Borrow/Copy congruences via subtype-
3142+
inclusion of [free_regions] on inner-vs-outer). The HARD cases
3143+
remain [admit] inside the lemma body: S_Let_Step, S_LetLin_Step,
3144+
S_App_Step2, S_If_Step, S_Pair_Step1/2 (when [r] is in the
3145+
sibling type's free regions), S_Inl_Step, S_Inr_Step,
3146+
S_Case_Step, S_Region_Step's [T_Region_L1] sub-case.
3147+
3148+
**Why the hard cases admit.** The inner step's typing-rule type
3149+
[T_inner] is NOT necessarily related to the outer type [T_outer]
3150+
by free_regions inclusion. E.g., T_Let_L1's outer type [T2] is
3151+
independent of the inner [T1]: the inner step can pop a region
3152+
that's in [free_regions T2] without violating any inner-typing
3153+
side condition. Operationally that's the §4.8 soundness gap
3154+
(lambda-rigidity / variable-typing permissive at L1) surfacing —
3155+
same family of obstacles as S_App_Step2 / S_Pair_Step2 / S_Let
3156+
cases in [preservation_l1] itself.
3157+
3158+
**Closure path (per PRESERVATION-DESIGN.md §4.8.1 + §5.1).** The
3159+
§4.8 path-(3) strengthening of [T_Var_*_L1] (premise
3160+
[forall r, In r (free_regions T) -> In r R]) propagates the
3161+
region constraint into variable-use sites and would discharge
3162+
most of these admits via structural induction on the typing
3163+
derivation. Path (1) — effect-typed lambdas / TFunEff (PR #200)
3164+
— also helps for S_App_Step2 specifically. Tracked at ephapax
3165+
issues #240 / #241 / #242 (Phase 3b Stage 2 / 3 / 4).
3166+
3167+
**Effect on P06's downstream goal.** Because the lemma is
3168+
[Admitted] (not Qed), USING it to close
3169+
[preservation_l1]'s S_StringConcat_Step2 case would only relay
3170+
the admit one level up — no net axiom-count improvement. We
3171+
therefore keep [preservation_l1]'s single outer [admit.] in
3172+
place; this commit's value is (a) the lemma statement
3173+
crystallises the obligation in mechanised form, (b) the Qed'd
3174+
sub-proofs cover ~70% of the step-rule cases (concretely:
3175+
atomic rules + the 5 EASY congruences listed above), and
3176+
(c) the admit comments map cleanly to ephapax issues
3177+
#240 / #241 / #242 for follow-up. *)
3178+
Lemma step_pop_disjoint_from_type_l1 :
3179+
forall mu R e mu' R' e' m G T R_final G',
3180+
(mu, R, e) -->> (mu', R', e') ->
3181+
has_type_l1 m R G e T R_final G' ->
3182+
forall r, In r (Typing.free_regions T) -> In r R -> In r R'.
3183+
Proof.
3184+
intros mu R e mu' R' e' m G T R_final G' Hstep.
3185+
remember (mu, R, e) as cfg eqn:Hcfg.
3186+
remember (mu', R', e') as cfg' eqn:Hcfg'.
3187+
revert mu R e mu' R' e' Hcfg Hcfg' m G T R_final G'.
3188+
induction Hstep;
3189+
intros mu0 R0 e0 mu0' R0' e0' Hcfg Hcfg'
3190+
m0 G0 T0 R_final0 G0_out Ht r0 Hfree HinR;
3191+
inversion Hcfg; subst; clear Hcfg;
3192+
inversion Hcfg'; subst; clear Hcfg'.
3193+
- (* S_StringNew: R' = R. *) exact HinR.
3194+
- (* S_StringConcat: ELoc + ELoc -> ELoc. R' = R. *) exact HinR.
3195+
- (* S_StringConcat_Step1: inner step on e1. T_StringConcat_L1
3196+
gives e1 : TString r at R; inner type's free_regions = outer's
3197+
free_regions ([r] in both). IH applies directly. *)
3198+
inversion Ht; subst.
3199+
match goal with
3200+
| [ He1 : has_type_l1 _ _ _ e1 (TString ?rr) _ _ |- _ ] =>
3201+
eapply IHHstep with (T := TString rr); try reflexivity; eassumption
3202+
end.
3203+
- (* S_StringConcat_Step2: inner step on e2 at R1; v1 is a value,
3204+
so by value_R_G_preserving_l1 R1 = R0. e2 has same outer type
3205+
(TString r). IH applies. *)
3206+
inversion Ht; subst.
3207+
match goal with
3208+
| [ Hv1 : has_type_l1 _ R0 _ v1 _ ?R1' _,
3209+
He2 : has_type_l1 _ ?R1' _ e2 (TString ?rr) _ _ |- _ ] =>
3210+
let HR1 := fresh "HR1" in
3211+
let HG1 := fresh "HG1" in
3212+
pose proof (value_R_G_preserving_l1 _ _ _ _ _ _ _ H Hv1) as [HR1 HG1];
3213+
subst R1' ;
3214+
eapply IHHstep with (T := TString rr); try reflexivity; eassumption
3215+
end.
3216+
- (* S_StringLen: R' = R. *) exact HinR.
3217+
- (* S_StringLen_Step: outer type = TBase TI32, free_regions = [].
3218+
Hfree is vacuous. *)
3219+
inversion Ht; subst. simpl in Hfree. exfalso; exact Hfree.
3220+
- (* S_Let_Val: substitution, R' = R. *) exact HinR.
3221+
- (* S_Let_Step: inner step on e1 at R0; outer type T2 is e2's
3222+
type, not e1's type. The inner step's type T1 is independent
3223+
of T2; if [r0] is in free_regions T2 but not in free_regions
3224+
T1, the inner step might pop [r0] without violating any
3225+
inner-typing side condition.
3226+
BLOCKED on §4.8 path (3): T_Var_*_L1 strengthening
3227+
(ephapax#240 / #241). *)
3228+
admit.
3229+
- (* S_LetLin_Val: substitution, R' = R. *) exact HinR.
3230+
- (* S_LetLin_Step: same blocker as S_Let_Step. *)
3231+
admit.
3232+
- (* S_App_Fun: substitution, R' = R. *) exact HinR.
3233+
- (* S_App_Step1: inner step on e1, type TFun T1 T2. free_regions
3234+
(TFun T1 T2) = free_regions T1 ++ free_regions T2; outer T2's
3235+
free_regions ⊆ inner's. So [In r0 (free_regions T2)] implies
3236+
[In r0 (free_regions (TFun T1 T2))]. IH applies. *)
3237+
inversion Ht; subst.
3238+
match goal with
3239+
| [ He1 : has_type_l1 _ _ _ e1 (TFun ?T1' ?T2') _ _ |- _ ] =>
3240+
eapply IHHstep with (T := TFun T1' T2'); try reflexivity; try eassumption;
3241+
simpl; apply in_or_app; right; exact Hfree
3242+
end.
3243+
- (* S_App_Step2: inner step on e2 at R1; v1 is a value so R1 = R0.
3244+
Inner type is T1 (argument type); outer type is T2 (return).
3245+
T1 and T2 unrelated by free_regions. BLOCKED on
3246+
lambda-rigidity gap (§4.8, ephapax#240 / #241 / #242). *)
3247+
admit.
3248+
- (* S_If_True: R' = R. *) exact HinR.
3249+
- (* S_If_False: R' = R. *) exact HinR.
3250+
- (* S_If_Step: inner step on e1, type TBase TBool (free_regions
3251+
= []); outer T can have any free_regions. BLOCKED on §4.8
3252+
(T_Var_*_L1 strengthening, ephapax#240 / #241). *)
3253+
admit.
3254+
- (* S_Pair_Step1: inner step on e1, type T1. Outer TProd T1 T2
3255+
has free_regions = free_regions T1 ++ free_regions T2.
3256+
Hfree case-split:
3257+
* In r0 (free_regions T1): IH on inner closes.
3258+
* In r0 (free_regions T2) only: BLOCKED on §4.8 (the inner
3259+
step could pop a region in T2's free regions without
3260+
violating any T1 side condition). *)
3261+
inversion Ht; subst.
3262+
simpl in Hfree. apply in_app_or in Hfree. destruct Hfree as [Hf1 | Hf2].
3263+
+ (* In r0 (free_regions T1): IH applies. *)
3264+
match goal with
3265+
| [ He1 : has_type_l1 _ _ _ e1 ?T1' _ _ |- _ ] =>
3266+
eapply IHHstep with (T := T1'); try reflexivity; eassumption
3267+
end.
3268+
+ (* In r0 (free_regions T2) only — BLOCKED on §4.8 (#240/#241). *)
3269+
admit.
3270+
- (* S_Pair_Step2: symmetric to S_Pair_Step1.
3271+
* In r0 (free_regions T2): IH on inner closes (v1 value gives
3272+
R1 = R0 via value_R_G_preserving_l1).
3273+
* In r0 (free_regions T1) only: BLOCKED on §4.8. *)
3274+
inversion Ht; subst.
3275+
simpl in Hfree. apply in_app_or in Hfree. destruct Hfree as [Hf1 | Hf2].
3276+
+ (* In r0 (free_regions T1) only — BLOCKED on §4.8. *)
3277+
admit.
3278+
+ (* In r0 (free_regions T2): IH applies after value_R_G_preserving_l1. *)
3279+
match goal with
3280+
| [ Hv1 : has_type_l1 _ R0 _ v1 _ ?R1' _,
3281+
He2 : has_type_l1 _ ?R1' _ e2 ?T2' _ _ |- _ ] =>
3282+
let HR1 := fresh "HR1" in
3283+
let HG1 := fresh "HG1" in
3284+
pose proof (value_R_G_preserving_l1 _ _ _ _ _ _ _ H Hv1) as [HR1 HG1];
3285+
subst R1';
3286+
eapply IHHstep with (T := T2'); try reflexivity; eassumption
3287+
end.
3288+
- (* S_Fst: ESnd (EPair v1 v2) atomic, R' = R. *) exact HinR.
3289+
- (* S_Fst_Step: inner step on e, type TProd T1 T2; outer T1.
3290+
free_regions T1 ⊆ free_regions (TProd T1 T2). IH applies. *)
3291+
inversion Ht; subst.
3292+
match goal with
3293+
| [ He : has_type_l1 _ _ _ e (TProd ?T1' ?T2') _ _ |- _ ] =>
3294+
eapply IHHstep with (T := TProd T1' T2'); try reflexivity; try eassumption;
3295+
simpl; apply in_or_app; left; exact Hfree
3296+
end.
3297+
- (* S_Snd: R' = R. *) exact HinR.
3298+
- (* S_Snd_Step: symmetric to S_Fst_Step. *)
3299+
inversion Ht; subst.
3300+
match goal with
3301+
| [ He : has_type_l1 _ _ _ e (TProd ?T1' ?T2') _ _ |- _ ] =>
3302+
eapply IHHstep with (T := TProd T1' T2'); try reflexivity; try eassumption;
3303+
simpl; apply in_or_app; right; exact Hfree
3304+
end.
3305+
- (* S_Inl_Step: inner type T1; outer TSum T1 T2. Case-split on
3306+
Hfree:
3307+
* In r0 (free_regions T1): IH applies.
3308+
* In r0 (free_regions T2) only: BLOCKED on §4.8. *)
3309+
inversion Ht; subst.
3310+
simpl in Hfree. apply in_app_or in Hfree. destruct Hfree as [Hf1 | Hf2].
3311+
+ match goal with
3312+
| [ He : has_type_l1 _ _ _ e ?T1' _ _ |- _ ] =>
3313+
eapply IHHstep with (T := T1'); try reflexivity; eassumption
3314+
end.
3315+
+ admit.
3316+
- (* S_Inr_Step: symmetric to S_Inl_Step.
3317+
* In r0 (free_regions T2): IH applies.
3318+
* In r0 (free_regions T1) only: BLOCKED on §4.8. *)
3319+
inversion Ht; subst.
3320+
simpl in Hfree. apply in_app_or in Hfree. destruct Hfree as [Hf1 | Hf2].
3321+
+ admit.
3322+
+ match goal with
3323+
| [ He : has_type_l1 _ _ _ e ?T2' _ _ |- _ ] =>
3324+
eapply IHHstep with (T := T2'); try reflexivity; eassumption
3325+
end.
3326+
- (* S_Case_Inl: substitution into branch e1, R' = R. *) exact HinR.
3327+
- (* S_Case_Inr: same. *) exact HinR.
3328+
- (* S_Case_Step: inner step on e (TSum T1 T2); outer T (branch
3329+
output type). Unrelated. BLOCKED on §4.8. *)
3330+
admit.
3331+
- (* S_Region_Enter: R' = r' :: R. In r0 R → In r0 R' (right of
3332+
cons). *)
3333+
simpl. right. exact HinR.
3334+
- (* S_Region_Exit: R' = remove_first r R. Typing of [ERegion r v]
3335+
at outer type T0 is either T_Region_L1 or T_Region_Active_L1
3336+
(the non-Echo variants); both have premise [~ In r (free_regions T0)].
3337+
Combined with Hfree : In r0 (free_regions T0), we get r ≠ r0.
3338+
Then [In r0 (remove_first r R0)] follows from [In r0 R0] +
3339+
[r ≠ r0]. *)
3340+
inversion Ht; subst;
3341+
match goal with
3342+
| [ Hnot : ~ In r R0 |- _ ] =>
3343+
(* T_Region_L1 / T_Region_L1_Echo: ~ In r R0 contradicts
3344+
H0 : In r R0 (S_Region_Exit's own premise). *)
3345+
exfalso; apply Hnot; assumption
3346+
| [ HnotT : ~ In r (Typing.free_regions ?T) |- _ ] =>
3347+
(* T_Region_Active_L1 / T_Region_Active_L1_Echo *)
3348+
let Hneq := fresh "Hneq" in
3349+
assert (Hneq : r <> r0) by
3350+
(intro Hbad; subst r0; apply HnotT; (exact Hfree || (simpl in Hfree; exact Hfree)));
3351+
apply remove_first_preserves_other; [exact Hneq | exact HinR]
3352+
end.
3353+
- (* S_Region_Exit_Echo: same as S_Region_Exit. Outer type is
3354+
TEcho T (one of the _Echo variants) or the regular T (from
3355+
legacy variants — but those don't pair with this step). *)
3356+
inversion Ht; subst;
3357+
match goal with
3358+
| [ Hnot : ~ In r R0 |- _ ] =>
3359+
exfalso; apply Hnot; assumption
3360+
| [ HnotT : ~ In r (Typing.free_regions ?T) |- _ ] =>
3361+
let Hneq := fresh "Hneq" in
3362+
assert (Hneq : r <> r0) by
3363+
(intro Hbad; subst r0; apply HnotT; (exact Hfree || (simpl in Hfree; exact Hfree)));
3364+
apply remove_first_preserves_other; [exact Hneq | exact HinR]
3365+
end.
3366+
- (* S_Region_Step: congruence on ERegion. Typing inversion gives
3367+
one of T_Region_L1 (body at r'::R), T_Region_Active_L1 (body at R),
3368+
T_Region_L1_Echo (same R-shape as T_Region_L1), or
3369+
T_Region_Active_L1_Echo (same R-shape as T_Region_Active_L1).
3370+
The Active variants close cleanly via IH (body typed at outer
3371+
R; output type = body type = outer T for non-Echo or witness
3372+
type for Echo). The non-Active variants (T_Region_L1 / Echo)
3373+
have body typed at (r'::R) but the step is at outer R, breaking
3374+
direct IH application. BLOCKED on bridging this mismatch
3375+
(Phase 3b follow-up, same family as the §4.8 gap). *)
3376+
inversion Ht; subst.
3377+
+ (* T_Region_L1: body at r' :: R0, step at R0. MISMATCH. *)
3378+
admit.
3379+
+ (* T_Region_Active_L1: body typed at R0 with type T0; IH applies
3380+
directly with body's typing. *)
3381+
match goal with
3382+
| [ He : has_type_l1 _ R0 _ e ?T' _ _ |- _ ] =>
3383+
eapply IHHstep with (T := T'); try reflexivity; eassumption
3384+
end.
3385+
+ (* T_Region_L1_Echo: body at r' :: R0, step at R0. MISMATCH. *)
3386+
admit.
3387+
+ (* T_Region_Active_L1_Echo: body typed at R0 with witness type T;
3388+
outer type TEcho T, free_regions same. IH applies. *)
3389+
match goal with
3390+
| [ He : has_type_l1 _ R0 _ e ?T' _ _ |- _ ] =>
3391+
eapply IHHstep with (T := T'); try reflexivity;
3392+
try eassumption;
3393+
(* Hfree : In r0 (free_regions (TEcho T')) which equals
3394+
free_regions T' definitionally. *)
3395+
simpl in Hfree; exact Hfree
3396+
end.
3397+
- (* S_Borrow_Step: T_Borrow_L1 forces e = EVar (no step rule),
3398+
T_Borrow_Val_L1 forces is_value of inner (no step from a
3399+
value, closed via legacy [values_dont_step]). Both cases
3400+
vacuous. *)
3401+
inversion Ht; subst.
3402+
1: { (* T_Borrow_L1: inner e = EVar i. *)
3403+
inversion Hstep. }
3404+
1: { (* T_Borrow_Val_L1: is_value of inner. *)
3405+
exfalso.
3406+
match goal with
3407+
| [ Hv : is_value _ |- _ ] =>
3408+
eapply values_dont_step; [exact Hv | exact Hstep]
3409+
end. }
3410+
- (* S_Drop: atomic, R' = R. *) exact HinR.
3411+
- (* S_Drop_Echo: atomic, R' = R. *) exact HinR.
3412+
- (* S_Drop_Step: inner type T (linear); outer TBase TUnit (via
3413+
T_Drop_L1, free_regions = []) or TEcho T (via T_Drop_L1_Echo,
3414+
free_regions = free_regions T). For T_Drop_L1: Hfree vacuous.
3415+
For T_Drop_L1_Echo: IH applies on inner T. *)
3416+
inversion Ht; subst.
3417+
+ (* T_Drop_L1 *) simpl in Hfree. exfalso; exact Hfree.
3418+
+ (* T_Drop_L1_Echo *)
3419+
match goal with
3420+
| [ He : has_type_l1 _ _ _ e ?T1' _ _ |- _ ] =>
3421+
eapply IHHstep with (T := T1'); try reflexivity; try eassumption
3422+
end.
3423+
- (* S_Copy: atomic, R' = R. *) exact HinR.
3424+
- (* S_Copy_Step: inner type T (non-linear); outer TProd T T;
3425+
free_regions = free_regions T ++ free_regions T. IH on
3426+
either side closes. *)
3427+
inversion Ht; subst.
3428+
match goal with
3429+
| [ He : has_type_l1 _ _ _ e ?T1' _ _ |- _ ] =>
3430+
eapply IHHstep with (T := T1'); try reflexivity; try eassumption;
3431+
simpl in Hfree; apply in_app_or in Hfree; destruct Hfree as [Hf | Hf]; exact Hf
3432+
end.
3433+
Admitted.
3434+
3435+
(** [Print Assumptions step_pop_disjoint_from_type_l1.] is emitted at
3436+
file end (alongside the other [Print Assumptions] audit calls) to
3437+
certify which axioms / admits this lemma depends on. *)
3438+
31203439
Theorem preservation_l1 :
31213440
forall m mu R e mu' R' e',
31223441
step (mu, R, e) (mu', R', e') ->
@@ -3309,3 +3628,27 @@ Print Assumptions preservation_l1.
33093628
Print Assumptions preservation_l3_region_active_echo.
33103629
Print Assumptions preservation_l3_drop_echo.
33113630
Print Assumptions preservation_l3.
3631+
3632+
(** ** P06 — axiom-dependency audit of [step_pop_disjoint_from_type_l1].
3633+
3634+
[step_pop_disjoint_from_type_l1] is [Admitted] in this commit (the
3635+
HARD cases — S_Let_Step, S_LetLin_Step, S_App_Step2, S_If_Step,
3636+
S_Pair_Step1/2, S_Inl_Step, S_Inr_Step, S_Case_Step, S_Region_Step
3637+
T_Region_L1 sub-case — are blocked on the §4.8 lambda-rigidity /
3638+
variable-typing strengthening, tracked at ephapax issues
3639+
#240 / #241 / #242).
3640+
3641+
The EASY cases (atomic non-region step rules; S_Region_Enter /
3642+
Exit / Exit_Echo; S_StringConcat_Step1/2; S_App_Step1;
3643+
S_Fst_Step / S_Snd_Step; S_Borrow_Step; S_Drop_Step; S_Copy_Step)
3644+
are Qed-closed via direct case analysis. The lemma's overall
3645+
status is therefore "Admitted" but with a structured proof body
3646+
enumerating the obstacle per case.
3647+
3648+
[Print Assumptions] will list the lemma itself as an axiom (the
3649+
Admitted form). When all internal admits close, this directive
3650+
will show only the file's pre-existing axiom +
3651+
[region_liveness_at_split_l1_gen] +
3652+
[region_shrink_preserves_typing_l1_gen_m]'s structural admit. *)
3653+
3654+
Print Assumptions step_pop_disjoint_from_type_l1.

0 commit comments

Comments
 (0)