Skip to content

Commit 59b4c51

Browse files
proofs(P43): port canonical_* forms to the L1 modality-polymorphic judgment (#274)
## Summary Closes proof-debt **P43** prerequisite from the comprehensive proof inventory. Prerequisite for **P42** (`progress_l1`) — half of the conventional type-soundness story. ## What lands Seven modality-polymorphic canonical-forms lemmas at the end of `formal/Semantics_L1.v`, mirroring the legacy Linear-only versions at `formal/Semantics.v:603-630`: | Lemma | Statement | |---|---| | `canonical_unit_l1_m` | `v : TBase TUnit + is_value v → v = EUnit` | | `canonical_bool_l1_m` | `v : TBase TBool + is_value v → ∃ b, v = EBool b` | | `canonical_i32_l1_m` | `v : TBase TI32 + is_value v → ∃ n, v = EI32 n` | | `canonical_fun_l1_m` | `v : TFun T1 T2 + is_value v → ∃ body, v = ELam T1 body` | | `canonical_prod_l1_m` | `v : TProd T1 T2 + is_value v → ∃ v1 v2, v = EPair v1 v2 ∧ ...` | | `canonical_sum_l1_m` | `v : TSum T1 T2 + is_value v → (∃ v0, EInl) ∨ (∃ v0, EInr)` | | `canonical_string_l1_m` | `v : TString r + is_value v → ∃ l, v = ELoc l r` | The `_m` suffix follows the convention established by `region_shrink_preserves_typing_l1_gen_m` and `subst_typing_gen_l1_m`. A pre-existing Linear-only `canonical_string_l1` at line 908 is left untouched (it predates the L2 modality hybrid; the new `_m` version generalises it). ## Proof shape All 7 proofs are single-line inversions following the legacy template: \`\`\`coq intros; inversion H0; subst; inversion H; subst; <discharge>. \`\`\` ## Audit All 7 `Print Assumptions` blocks (added inline) print **`Closed under the global context`** — these lemmas surface ZERO axioms. ## Next steps `progress_l1` (P42) builds on these via case analysis on the type of a closed well-typed value. Stated separately because it requires the step relation's totality on non-value terms — a larger PR-sized scope. ## Test plan - [x] `just -f formal/Justfile all` clean - [x] All 7 Print Assumptions print "Closed under the global context" - [x] Build oracle confirms zero new admits / axioms 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent a1d569c commit 59b4c51

1 file changed

Lines changed: 83 additions & 0 deletions

File tree

formal/Semantics_L1.v

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3652,3 +3652,86 @@ Print Assumptions preservation_l3.
36523652
[region_shrink_preserves_typing_l1_gen_m]'s structural admit. *)
36533653

36543654
Print Assumptions step_pop_disjoint_from_type_l1.
3655+
3656+
(** ============================================================
3657+
Canonical forms for the L1 judgment (proof-debt P43)
3658+
============================================================
3659+
3660+
Mirror of the legacy [canonical_*] lemmas at [Semantics.v:603-630]
3661+
on the [has_type_l1] judgment. Together these are the
3662+
prerequisite for [progress_l1] (proof-debt P42).
3663+
3664+
A canonical-forms lemma reads: "if [v] is a value of type [T],
3665+
then [v] is of the canonical syntactic shape for [T]". This is
3666+
invertibility of value-typing rules from the value side: it
3667+
inverts the [is_value v] view of a closed [has_type_l1] derivation
3668+
into the constructor pattern of [v].
3669+
3670+
Modality-polymorphic by design — the structural property holds
3671+
in both [Linear] and [Affine] modes; the modality parameter
3672+
threads through inversion unchanged.
3673+
3674+
All 7 follow the same pattern as the legacy proofs: inversion on
3675+
[is_value v] (case-splits the value constructors), then inversion
3676+
on the typing derivation (rules that don't produce [T] are
3677+
contradictory). [eauto] discharges the existential witnesses. *)
3678+
3679+
Lemma canonical_unit_l1_m :
3680+
forall m R R' G G' v,
3681+
has_type_l1 m R G v (TBase TUnit) R' G' -> is_value v -> v = EUnit.
3682+
Proof. intros; inversion H0; subst; inversion H; subst; reflexivity. Qed.
3683+
3684+
Lemma canonical_bool_l1_m :
3685+
forall m R R' G G' v,
3686+
has_type_l1 m R G v (TBase TBool) R' G' -> is_value v ->
3687+
exists b, v = EBool b.
3688+
Proof. intros; inversion H0; subst; inversion H; subst; eauto. Qed.
3689+
3690+
Lemma canonical_i32_l1_m :
3691+
forall m R R' G G' v,
3692+
has_type_l1 m R G v (TBase TI32) R' G' -> is_value v ->
3693+
exists n, v = EI32 n.
3694+
Proof. intros; inversion H0; subst; inversion H; subst; eauto. Qed.
3695+
3696+
Lemma canonical_fun_l1_m :
3697+
forall m R R' G G' v T1 T2,
3698+
has_type_l1 m R G v (TFun T1 T2) R' G' -> is_value v ->
3699+
exists body, v = ELam T1 body.
3700+
Proof. intros; inversion H0; subst; inversion H; subst; eauto. Qed.
3701+
3702+
Lemma canonical_prod_l1_m :
3703+
forall m R R' G G' v T1 T2,
3704+
has_type_l1 m R G v (TProd T1 T2) R' G' -> is_value v ->
3705+
exists v1 v2, v = EPair v1 v2 /\ is_value v1 /\ is_value v2.
3706+
Proof. intros; inversion H0; subst; inversion H; subst; eexists _, _; auto. Qed.
3707+
3708+
Lemma canonical_sum_l1_m :
3709+
forall m R R' G G' v T1 T2,
3710+
has_type_l1 m R G v (TSum T1 T2) R' G' -> is_value v ->
3711+
(exists T v0, v = EInl T v0 /\ is_value v0) \/
3712+
(exists T v0, v = EInr T v0 /\ is_value v0).
3713+
Proof.
3714+
intros; inversion H0; subst; inversion H; subst;
3715+
[left|right]; eexists _, _; auto.
3716+
Qed.
3717+
3718+
Lemma canonical_string_l1_m :
3719+
forall m R R' G G' v r,
3720+
has_type_l1 m R G v (TString r) R' G' -> is_value v ->
3721+
exists l, v = ELoc l r.
3722+
Proof. intros; inversion H0; subst; inversion H; subst; eauto. Qed.
3723+
3724+
(** ============================================================
3725+
Print Assumptions — Canonical-forms axiom audit
3726+
============================================================
3727+
Verify each canonical-forms lemma is clean: their statement is
3728+
structurally derivable from the typing-rule shapes + [is_value]
3729+
inversion, so they should not surface any axiom. *)
3730+
3731+
Print Assumptions canonical_unit_l1_m.
3732+
Print Assumptions canonical_bool_l1_m.
3733+
Print Assumptions canonical_i32_l1_m.
3734+
Print Assumptions canonical_fun_l1_m.
3735+
Print Assumptions canonical_prod_l1_m.
3736+
Print Assumptions canonical_sum_l1_m.
3737+
Print Assumptions canonical_string_l1_m.

0 commit comments

Comments
 (0)