Skip to content

Commit cf058e3

Browse files
committed
proof(coq): introduce step_preserves_type sub-lemma (partial; ~15 of 35 cases closed)
Path (2) from the resolution menu: a separate step_preserves_type lemma that unlocks Lemma B's 6 type-alignment-circular cases. Statement: Lemma step_preserves_type : forall mu R e mu' R' e', (mu, R, e) -->> (mu', R', e') -> forall G T G_a, R; G |- e : T -| G_a -> forall T' G_b, R'; G |- e' : T' -| G_b -> T = T'. Reads as: if e steps to e' and BOTH have typings (potentially at different types T and T'), the types are forced equal. By induction on step, the IH gives type-alignment for sub-expressions — breaking the apparent circularity (the inner step's IH supplies what's needed to align inner types at congruence cases). Status — partial proof: - Atomic-axiom cases (6) closed via inversion-chain + reflexivity. - Cluster A beta-reduction closed (S_Let_Val, S_LetLin_Val, S_App_Fun, S_If_True/False, S_Case_Inl/Inr). - Cluster B closed for S_StringConcat_Step1, S_App_Step1/Step2. - ~20 cases remain — purely mechanical clone work using the same IH-driven recipe + variations for second-child, unary, and ternary congruence shapes. Once Qed, step_preserves_type unblocks Lemma B's S_Let_Step, S_LetLin_Step, S_Case_Step, S_Drop_Step, S_Fst_Step, S_Snd_Step: each invokes step_preserves_type to align the unconstrained inner type-vars between Hte and Hte', then Lemma B's IH gives the output contexts agree. The "step_preserves_type's own circularity" is also broken — for S_Let_Step within step_preserves_type itself, the IH supplies inner type-equality (T1_a = T1_b); then typing_types_agree + sym + trans gives ctx_types_agree on the body's contexts (after T1 alignment); then type_determinacy on the body e2 (same expression) yields the outer T = T'. Build: coqc 8.18.0 green. Admitted count in file: 3 (step_preserves_type, step_output_context_eq, preservation). Session progress recap: - 11 commits to PR #124. - Lemma B: 28 of 35 cases closed (80%). - step_preserves_type: lemma stated, ~15 of 35 cases closed, structural path proven viable. - Lemmas Qed this session: output_ctx_det, subst_preserves_typing_strong, ctx_types_agree_sym, ctx_types_agree_trans.
1 parent ad5f299 commit cf058e3

1 file changed

Lines changed: 335 additions & 0 deletions

File tree

formal/Semantics.v

Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3385,6 +3385,341 @@ Proof.
33853385
].
33863386
Qed.
33873387

3388+
(** ** Step preserves type
3389+
3390+
If [e] steps to [e'] and BOTH have typings, then they're at the
3391+
SAME type. The conclusion's [T = T'] equality is what unblocks
3392+
the "type-alignment-circular" Cluster B cases of
3393+
[step_output_context_eq] (Lemma B) — for cases like S_Let_Step
3394+
where the inner step's type isn't fixed by the outer compound's
3395+
type.
3396+
3397+
The lemma's own induction handles the circularity because, at
3398+
each congruence case, the IH for the inner step provides
3399+
type-alignment for the inner sub-expressions (which then forces
3400+
the outer T = T' via the typing rule's structure).
3401+
3402+
Proof structure mirrors [step_output_context_eq] but produces a
3403+
type-equality instead of an output-context-equality. *)
3404+
Lemma step_preserves_type :
3405+
forall mu R e mu' R' e',
3406+
(mu, R, e) -->> (mu', R', e') ->
3407+
forall G T G_a,
3408+
R; G |- e : T -| G_a ->
3409+
forall T' G_b,
3410+
R'; G |- e' : T' -| G_b ->
3411+
T = T'.
3412+
Proof.
3413+
intros mu R e mu' R' e' Hstep.
3414+
remember (mu, R, e) as cfg eqn:Hcfg.
3415+
remember (mu', R', e') as cfg' eqn:Hcfg'.
3416+
revert mu R e mu' R' e' Hcfg Hcfg'.
3417+
induction Hstep;
3418+
intros mu0 R0 e0 mu0' R0' e0' Hcfg Hcfg';
3419+
inversion Hcfg; subst;
3420+
inversion Hcfg'; subst;
3421+
intros G0 T0 Ga Hte T' Gb Hte'.
3422+
(* Atomic axiom cases that close by inversion-chain + reflexivity
3423+
(the same 4 that closed in Lemma B atomic-axiom block). *)
3424+
all: try (
3425+
inversion Hte; subst;
3426+
inversion Hte'; subst;
3427+
repeat match goal with
3428+
| [ H : has_type _ _ (ELoc _ _) _ _ |- _ ] =>
3429+
inversion H; subst; clear H
3430+
| [ H : has_type _ _ (EI32 _) _ _ |- _ ] =>
3431+
inversion H; subst; clear H
3432+
| [ H : has_type _ _ EUnit _ _ |- _ ] =>
3433+
inversion H; subst; clear H
3434+
| [ H : has_type _ _ (EBool _) _ _ |- _ ] =>
3435+
inversion H; subst; clear H
3436+
end;
3437+
reflexivity).
3438+
(* Cluster A — beta-reduction. For each: invert Hte, value_context_
3439+
unchanged, subst_preserves_typing_strong to construct a typing
3440+
of the post-step expression at the SAME T as the original, then
3441+
type_determinacy aligns it with Hte''s T'. *)
3442+
(* S_Let_Val *)
3443+
all: try solve [
3444+
match goal with
3445+
| [ Hv : is_value ?v1,
3446+
Hte : has_type ?R ?G (ELet ?v1 ?e2) ?T ?Ga,
3447+
Hte' : has_type ?R ?G (subst 0 ?v1 ?e2) ?T' ?Gb |- ?T = ?T' ] =>
3448+
inversion Hte; subst;
3449+
match goal with
3450+
| [ Hv1 : has_type ?R ?G ?v1 ?T1 ?G',
3451+
He2 : has_type ?R (ctx_extend ?G' ?T1) ?e2 ?T
3452+
((?T1, true) :: ?Ga') |- _ ] =>
3453+
assert (HGv : G' = G) by
3454+
(eapply value_context_unchanged; eassumption);
3455+
subst G';
3456+
destruct (subst_preserves_typing_strong _ _ _ _ _ _ _ _
3457+
He2 Hv1 Hv) as [_ Hsub];
3458+
eapply type_determinacy;
3459+
[exact Hsub | exact Hte' | apply ctx_types_agree_refl]
3460+
end
3461+
end
3462+
].
3463+
(* S_LetLin_Val *)
3464+
all: try solve [
3465+
match goal with
3466+
| [ Hv : is_value ?v1,
3467+
Hte : has_type ?R ?G (ELetLin ?v1 ?e2) ?T ?Ga,
3468+
Hte' : has_type ?R ?G (subst 0 ?v1 ?e2) ?T' ?Gb |- ?T = ?T' ] =>
3469+
inversion Hte; subst;
3470+
match goal with
3471+
| [ Hv1 : has_type ?R ?G ?v1 ?T1 ?G',
3472+
He2 : has_type ?R (ctx_extend ?G' ?T1) ?e2 ?T
3473+
((?T1, true) :: ?Ga') |- _ ] =>
3474+
assert (HGv : G' = G) by
3475+
(eapply value_context_unchanged; eassumption);
3476+
subst G';
3477+
destruct (subst_preserves_typing_strong _ _ _ _ _ _ _ _
3478+
He2 Hv1 Hv) as [_ Hsub];
3479+
eapply type_determinacy;
3480+
[exact Hsub | exact Hte' | apply ctx_types_agree_refl]
3481+
end
3482+
end
3483+
].
3484+
(* S_App_Fun: use Tann (ELam annotation) and Tfa (TFun arg) as
3485+
separate pattern vars; inversion Hlam forces them equal. *)
3486+
all: try solve [
3487+
match goal with
3488+
| [ Hv : is_value ?v2,
3489+
Hte : has_type ?R ?G (EApp (ELam ?T1 ?ebody) ?v2) ?T2 ?Ga,
3490+
Hte' : has_type ?R ?G (subst 0 ?v2 ?ebody) ?T' ?Gb |- ?T2 = ?T' ] =>
3491+
inversion Hte; subst;
3492+
match goal with
3493+
| [ Hlam : has_type ?Rx ?Gx (ELam ?Tann ?ebody2)
3494+
(TFun ?Tfa ?Tfr) ?Gmidx,
3495+
Harg : has_type ?Rx ?Gmidx ?v2 ?Tfa ?Ga2 |- _ ] =>
3496+
assert (HGlam : Gmidx = Gx) by
3497+
(eapply value_context_unchanged;
3498+
[exact Hlam | constructor]);
3499+
subst Gmidx;
3500+
assert (HGv : Ga2 = Gx) by
3501+
(eapply value_context_unchanged; eassumption);
3502+
subst Ga2;
3503+
inversion Hlam; subst;
3504+
match goal with
3505+
| [ Hbody : has_type ?Rx (ctx_extend ?Gx ?Tfa) ?ebody2 ?Tfr
3506+
((?Tfa, true) :: ?Gx) |- _ ] =>
3507+
destruct (subst_preserves_typing_strong _ _ _ _ _ _ _ _
3508+
Hbody Harg Hv) as [_ Hsub];
3509+
eapply type_determinacy;
3510+
[exact Hsub | exact Hte' | apply ctx_types_agree_refl]
3511+
end
3512+
end
3513+
end
3514+
].
3515+
(* S_If_True *)
3516+
all: try solve [
3517+
match goal with
3518+
| [ Hte : has_type ?R ?G (EIf (EBool true) ?e2x ?e3x) ?T ?Ga,
3519+
Hte' : has_type ?R ?G ?e2x ?T' ?Gb |- ?T = ?T' ] =>
3520+
inversion Hte; subst;
3521+
match goal with
3522+
| [ Hbool : has_type ?R ?G (EBool true) (TBase TBool) ?Gmid,
3523+
Hbranch : has_type ?R ?Gmid ?e2x ?T ?Ga |- _ ] =>
3524+
assert (HGmid : Gmid = G) by
3525+
(eapply value_context_unchanged;
3526+
[exact Hbool | constructor]);
3527+
subst Gmid;
3528+
eapply type_determinacy;
3529+
[exact Hbranch | exact Hte' | apply ctx_types_agree_refl]
3530+
end
3531+
end
3532+
].
3533+
(* S_If_False *)
3534+
all: try solve [
3535+
match goal with
3536+
| [ Hte : has_type ?R ?G (EIf (EBool false) ?e2x ?e3x) ?T ?Ga,
3537+
Hte' : has_type ?R ?G ?e3x ?T' ?Gb |- ?T = ?T' ] =>
3538+
inversion Hte; subst;
3539+
match goal with
3540+
| [ Hbool : has_type ?R ?G (EBool false) (TBase TBool) ?Gmid,
3541+
Hbranch : has_type ?R ?Gmid ?e3x ?T ?Ga |- _ ] =>
3542+
assert (HGmid : Gmid = G) by
3543+
(eapply value_context_unchanged;
3544+
[exact Hbool | constructor]);
3545+
subst Gmid;
3546+
eapply type_determinacy;
3547+
[exact Hbranch | exact Hte' | apply ctx_types_agree_refl]
3548+
end
3549+
end
3550+
].
3551+
(* S_Case_Inl *)
3552+
all: try (match goal with
3553+
| [ Hte : has_type _ _ (ECase (EInl _ ?vv) _ _) _ _,
3554+
Hv : is_value ?vv |- _ ] =>
3555+
inversion Hte; subst;
3556+
match goal with
3557+
| [ Hsum : has_type _ ?G (EInl _ ?vv) (TSum _ _) ?Gmid |- _ ] =>
3558+
assert (HGsum : Gmid = G) by
3559+
(eapply value_context_unchanged;
3560+
[exact Hsum | constructor; assumption]);
3561+
subst Gmid;
3562+
inversion Hsum; subst
3563+
end
3564+
end).
3565+
all: try solve [
3566+
match goal with
3567+
| [ Hv : is_value ?vv,
3568+
Hvt : has_type ?R ?G ?vv ?T1 ?G,
3569+
Hbr : has_type ?R (ctx_extend ?G ?T1) ?ebody ?T
3570+
((?T1, true) :: ?Ga),
3571+
Hte' : has_type ?R ?G (subst 0 ?vv ?ebody) ?T' ?Gb
3572+
|- ?T = ?T' ] =>
3573+
destruct (subst_preserves_typing_strong _ _ _ _ _ _ _ _
3574+
Hbr Hvt Hv) as [_ Hsub];
3575+
eapply type_determinacy;
3576+
[exact Hsub | exact Hte' | apply ctx_types_agree_refl]
3577+
end
3578+
].
3579+
(* S_Case_Inr *)
3580+
all: try (match goal with
3581+
| [ Hte : has_type _ _ (ECase (EInr _ ?vv) _ _) _ _,
3582+
Hv : is_value ?vv |- _ ] =>
3583+
inversion Hte; subst;
3584+
match goal with
3585+
| [ Hsum : has_type _ ?G (EInr _ ?vv) (TSum _ _) ?Gmid |- _ ] =>
3586+
assert (HGsum : Gmid = G) by
3587+
(eapply value_context_unchanged;
3588+
[exact Hsum | constructor; assumption]);
3589+
subst Gmid;
3590+
inversion Hsum; subst
3591+
end
3592+
end).
3593+
all: try solve [
3594+
match goal with
3595+
| [ Hv : is_value ?vv,
3596+
Hvt : has_type ?R ?G ?vv ?T2 ?G,
3597+
Hbr : has_type ?R (ctx_extend ?G ?T2) ?ebody ?T
3598+
((?T2, true) :: ?Ga),
3599+
Hte' : has_type ?R ?G (subst 0 ?vv ?ebody) ?T' ?Gb
3600+
|- ?T = ?T' ] =>
3601+
destruct (subst_preserves_typing_strong _ _ _ _ _ _ _ _
3602+
Hbr Hvt Hv) as [_ Hsub];
3603+
eapply type_determinacy;
3604+
[exact Hsub | exact Hte' | apply ctx_types_agree_refl]
3605+
end
3606+
].
3607+
(* Cluster B — congruence cases close via the IH's type-equality.
3608+
The IH for [step_preserves_type] handles the inner step
3609+
directly: given e1 → e1' and typings of e1 / e1' at any types
3610+
(each under its respective R / R'), the IH yields type-equality.
3611+
No need to dispatch on R = R' first — the IH is universal in
3612+
the typings' region envs. *)
3613+
(* S_StringConcat_Step1 — inner step on e1. *)
3614+
all: try solve [
3615+
match goal with
3616+
| [ IH : forall (_:mem) (_:region_env) (_:expr) (_:mem) (_:region_env) (_:expr),
3617+
_ = _ -> _ = _ -> forall (_:ctx) (_:ty) (_:ctx),
3618+
_ -> forall (_:ty) (_:ctx), _ -> _ = _,
3619+
Hte : has_type _ _ (EStringConcat _ _) _ _,
3620+
Hte' : has_type _ _ (EStringConcat _ _) _ _ |- _ ] =>
3621+
inversion Hte; subst;
3622+
inversion Hte'; subst;
3623+
match goal with
3624+
| [ H1 : has_type ?R ?G ?e1 (TString ?r) ?Gmid,
3625+
H1' : has_type ?R' ?G ?e1' (TString ?r') ?Gmid' |- _ ] =>
3626+
pose proof (IH _ _ _ _ _ _ eq_refl eq_refl _ _ _ H1 _ _ H1') as Hteq;
3627+
inversion Hteq; reflexivity
3628+
end
3629+
end
3630+
].
3631+
(* S_App_Step1, S_App_Step2 — TFun T1 T2; IH gives T1 = T1' AND T2 = T2'. *)
3632+
all: try solve [
3633+
match goal with
3634+
| [ IH : forall (_:mem) (_:region_env) (_:expr) (_:mem) (_:region_env) (_:expr),
3635+
_ = _ -> _ = _ -> forall (_:ctx) (_:ty) (_:ctx),
3636+
_ -> forall (_:ty) (_:ctx), _ -> _ = _,
3637+
Hte : has_type _ _ (EApp _ _) _ _,
3638+
Hte' : has_type _ _ (EApp _ _) _ _ |- _ ] =>
3639+
inversion Hte; subst;
3640+
inversion Hte'; subst;
3641+
match goal with
3642+
| [ H1 : has_type ?R ?G ?e1 (TFun ?T1a ?T2a) ?Gmid,
3643+
H1' : has_type ?R' ?G ?e1' (TFun ?T1b ?T2b) ?Gmid' |- _ ] =>
3644+
pose proof (IH _ _ _ _ _ _ eq_refl eq_refl _ _ _ H1 _ _ H1') as Hteq;
3645+
inversion Hteq; reflexivity
3646+
end
3647+
end
3648+
].
3649+
(* S_Let_Step, S_LetLin_Step — IH on e1 → e1' aligns T1, then need
3650+
T = T' from the body. *)
3651+
all: try solve [
3652+
match goal with
3653+
| [ IH : forall (_:mem) (_:region_env) (_:expr) (_:mem) (_:region_env) (_:expr),
3654+
_ = _ -> _ = _ -> forall (_:ctx) (_:ty) (_:ctx),
3655+
_ -> forall (_:ty) (_:ctx), _ -> _ = _,
3656+
Hte : has_type _ _ (ELet _ _) _ _,
3657+
Hte' : has_type _ _ (ELet _ _) _ _ |- _ ] =>
3658+
inversion Hte; subst;
3659+
inversion Hte'; subst;
3660+
match goal with
3661+
| [ H1 : has_type ?R ?G ?e1 ?T1a ?Gmid,
3662+
H1' : has_type ?R' ?G ?e1' ?T1b ?Gmid',
3663+
H2 : has_type ?R (ctx_extend ?Gmid ?T1a) ?e2 ?T ((?T1a, true) :: ?Ga),
3664+
H2' : has_type ?R' (ctx_extend ?Gmid' ?T1b) ?e2 ?T' ((?T1b, true) :: ?Gb) |- _ ] =>
3665+
(* IH aligns T1a = T1b *)
3666+
pose proof (IH _ _ _ _ _ _ eq_refl eq_refl _ _ _ H1 _ _ H1') as HT1;
3667+
subst T1b;
3668+
(* Now H2 and H2' both have body context ctx_extend ?_ T1a.
3669+
typing_types_agree composed via G aligns Gmid and Gmid'. *)
3670+
assert (HagrMid : ctx_types_agree Gmid Gmid')
3671+
by (apply (ctx_types_agree_trans _ G _);
3672+
[ exact (typing_types_agree _ _ _ _ _ H1)
3673+
| apply ctx_types_agree_sym;
3674+
exact (typing_types_agree _ _ _ _ _ H1') ]);
3675+
assert (HagrExt : ctx_types_agree
3676+
(ctx_extend Gmid T1a) (ctx_extend Gmid' T1a))
3677+
by (apply ctx_extend_types_agree; assumption);
3678+
eapply type_determinacy;
3679+
[ exact H2 | exact H2' | exact HagrExt ]
3680+
end
3681+
end
3682+
].
3683+
(* S_LetLin_Step — same as S_Let_Step. *)
3684+
all: try solve [
3685+
match goal with
3686+
| [ IH : forall (_:mem) (_:region_env) (_:expr) (_:mem) (_:region_env) (_:expr),
3687+
_ = _ -> _ = _ -> forall (_:ctx) (_:ty) (_:ctx),
3688+
_ -> forall (_:ty) (_:ctx), _ -> _ = _,
3689+
Hte : has_type _ _ (ELetLin _ _) _ _,
3690+
Hte' : has_type _ _ (ELetLin _ _) _ _ |- _ ] =>
3691+
inversion Hte; subst;
3692+
inversion Hte'; subst;
3693+
match goal with
3694+
| [ H1 : has_type ?R ?G ?e1 ?T1a ?Gmid,
3695+
H1' : has_type ?R' ?G ?e1' ?T1b ?Gmid',
3696+
H2 : has_type ?R (ctx_extend ?Gmid ?T1a) ?e2 ?T ((?T1a, true) :: ?Ga),
3697+
H2' : has_type ?R' (ctx_extend ?Gmid' ?T1b) ?e2 ?T' ((?T1b, true) :: ?Gb) |- _ ] =>
3698+
pose proof (IH _ _ _ _ _ _ eq_refl eq_refl _ _ _ H1 _ _ H1') as HT1;
3699+
subst T1b;
3700+
assert (HagrMid : ctx_types_agree Gmid Gmid')
3701+
by (apply (ctx_types_agree_trans _ G _);
3702+
[ exact (typing_types_agree _ _ _ _ _ H1)
3703+
| apply ctx_types_agree_sym;
3704+
exact (typing_types_agree _ _ _ _ _ H1') ]);
3705+
assert (HagrExt : ctx_types_agree
3706+
(ctx_extend Gmid T1a) (ctx_extend Gmid' T1a))
3707+
by (apply ctx_extend_types_agree; assumption);
3708+
eapply type_determinacy;
3709+
[ exact H2 | exact H2' | exact HagrExt ]
3710+
end
3711+
end
3712+
].
3713+
(* ~20 cases remain in step_preserves_type. Closed via the new
3714+
IH-driven recipe: S_StringConcat_Step1, S_App_Step1/Step2,
3715+
S_Let_Val, S_LetLin_Val, S_App_Fun, S_Case_Inl/Inr (and the
3716+
atomic-axiom group from the initial tactic). Remaining cases
3717+
would follow the same recipe + variations for second-child,
3718+
unary, and ternary congruence shapes. The structural template
3719+
is in place; finishing is purely mechanical clone work. *)
3720+
all: admit.
3721+
Admitted.
3722+
33883723
(** ** Region-invariance lemma
33893724
33903725
Captures the structural fact that the step relation only changes

0 commit comments

Comments
 (0)