Skip to content

Commit 8200ed7

Browse files
feat(L1): Phase D slice 4 Phase 2 — subst_typing_gen_l1_m_ground_nonlinear + helpers (#220)
## Summary Phase 2 of the non-linear substitution-lemma generalisation per [`formal/SUBST-LEMMA-GENERALIZATION-DESIGN.md`](https://github.com/hyperpolymath/ephapax/blob/main/formal/SUBST-LEMMA-GENERALIZATION-DESIGN.md) §"Phase 2". Builds on Phase 1's `ground_nonlinear_retype_l1_m` (#219). Adds three pieces of NEW infrastructure to `formal/Semantics_L1.v`, all orthogonal to legacy preservation in `Semantics.v`: ### 1. Phase 1 generalisation `ground_nonlinear_retype_l1_m` extended from (m monomorphic, G monomorphic) to (m → m', G → G')-polymorphic. The 3 ground typing rules (`T_Unit_L1` / `T_Bool_L1` / `T_I32_L1`) are themselves polymorphic in both, so the proof is unchanged. Phase 2 needs the cross-modality bridge to lift the Linear-typed `Hv_type` into the active modality m inside the substitution lemma's compound cases. ### 2. `ground_nonlinear_value_shift_id_l1` helper Ground non-linear values (`EUnit` / `EBool b` / `EI32 n`) are closed terms, so de Bruijn `shift c d v = v` for any c, d. Used to rewrite away the `shift 0 1 vv` that `subst` introduces when descending through term binders. ### 3. `subst_typing_gen_l1_m_ground_nonlinear` parallel lemma ```coq forall m R Gin e T R' Gout, has_type_l1 m R Gin e T R' Gout -> forall k T1 v u_in, nth_error Gin k = Some (T1, u_in) -> is_value v -> is_ground_nonlinear_ty T1 = true -> R; remove_at k Gin |=L1 v : T1 -| R; remove_at k Gin -> forall u_out, nth_error Gout k = Some (T1, u_out) -> has_type_l1 m R (remove_at k Gin) (subst k v e) T R' (remove_at k Gout). ``` Mirrors `subst_typing_gen_l1_m`'s 28+ case structure. Three key divergences from the linear lemma: - **T_Var_Lin_L1 with `i = k0`**: rule's `is_linear_ty T = true` premise contradicts `is_ground_nonlinear_ty Tsub = true` (discharged via `exfalso`). - **T_Var_Unr_L1 with `i = k0`**: CONSTRUCTIVE here (the symmetric case in the linear lemma is the exfalso branch). The substituted value `vv` is lifted from Linear into the active modality m via `ground_nonlinear_retype_l1_m`. - **Compound rules**: `ground_nonlinear_retype_l1_m` replaces the `linear_value_is_loc_l1` + `loc_retype_at_R_l1_m` + `region_liveness_at_split_l1_gen` pipeline. The retype takes any R', G', m', so no liveness side-condition is required. ## Why this matters Phase 2 unblocks: - **Phase 3**: `tfuneff_lambda_retype_l1_m` + extend substitution to `TFunEff T1` lambdas. - **Phase 4**: close `preservation_l2`'s `T_App_L2_Eff` β-case for ground non-linear `T1` (in `TFunEff T1 T2 R_in R_out` lambdas with `T1 ∈ {TBase TUnit, TBase TBool, TBase TI32}`). Ships as a **sibling lemma** rather than folding case-split into the existing `subst_typing_gen_l1_m` to preserve the ~30 Qed downstreams. ## Owner-directive compliance Per `CLAUDE.md` 2026-05-27: - Does NOT close `Theorem preservation` in `Semantics.v`. - Does NOT extend `Semantics.v` / `Typing.v` / `Counterexample.v` (all untouched). - Does NOT close residual `Semantics_L1.v` admits via this work — strictly NEW infrastructure. - Adds no new `Axiom` or `Admitted` declarations. ## Test plan - [x] `just clean && just all` in `formal/` — clean rebuild of all 10 `.v` files (coqc 8.18.0). - [x] Zero new admits/axioms (all proofs `Qed`). - [x] `Semantics.v`/`Typing.v`/`Counterexample.v` untouched. - [x] GPG-signed commit. - [x] STATE.a2ml `next_action` shifted to Phase 3. ## Diff - `formal/Semantics_L1.v` +322 (lemma + 2 helpers + doc comments) - `.machine_readable/6a2/STATE.a2ml` +1/-1 (state journal advance) ## Refs Refs hyperpolymath/standards#134 (sub-issue of hyperpolymath/standards#124 estate proof-debt epic). Follows #219 (Phase 1). Phase 3 (TFunEff lambda retype) is the next slice. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e3d8651 commit 8200ed7

2 files changed

Lines changed: 322 additions & 5 deletions

File tree

.machine_readable/6a2/STATE.a2ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
@state(version="2.0"):
88
phase: "implementation"
9-
next_action: "Phase D slice 4 Phase 2 — ship `subst_typing_gen_l1_m_ground_nonlinear` per `formal/SUBST-LEMMA-GENERALIZATION-DESIGN.md` §'Phase 2'. Parallel substitution lemma for ground non-linear `T1` (TBase TUnit / TBase TBool / TBase TI32). Structure mirrors the existing `subst_typing_gen_l1_m` 28-case induction at `formal/Semantics_L1.v:1358`. Key divergences: (i) `T_Var_Lin_L1` with `i = k0` discharges via `is_linear_ty T1 = false` vs T_Var_Lin_L1's `is_linear_ty T = true` premise (exfalso); (ii) `T_Var_Unr_L1` with `i = k0` becomes a CONSTRUCTIVE case — apply `Hv_type` directly (in the existing lemma this is vacuous via `Hlin`); (iii) compound cases use `ground_nonlinear_retype_l1_m` (NEW — Phase 1, landed in PR #219) in place of `loc_retype_at_R_l1_m` for R-shift retypes. Estimated ~250-300 lines paralleling existing proof. Ships as sibling lemma (NOT case-split into existing one) to avoid breaking ~30 Qed downstreams of `subst_typing_gen_l1_m`. Anti-patterns to refuse (per CLAUDE.md owner directive): no `Admitted` to close cases; no touching `Semantics.v`/`Typing.v`/`Counterexample.v`; no closure of residual `Semantics_L1.v` admits via this work — strictly NEW infrastructure orthogonal to legacy. Coqc 8.18.0 is the only authority."
10-
last_action: "Phase D slice 4 Phase 1 LANDED (2026-05-30): `is_ground_nonlinear_ty` predicate added to `formal/Syntax.v` (after `is_linear_ty`); `ground_nonlinear_retype_l1_m` lemma added to `formal/Semantics_L1.v` (after `loc_retype_at_R_l1_m`). Signature: `forall m R R' G v T, is_value v → is_ground_nonlinear_ty T = true → has_type_l1 m R G v T R G → has_type_l1 m R' G v T R' G`. Proof: destruct on `is_value v` witness; in EUnit/EBool/EI32 cases invert typing and re-apply T_Unit_L1/T_Bool_L1/T_I32_L1 at R'; in non-ground value cases (ELam/EPair/EInl/EInr/ELoc/EBorrow/EEcho) every typing-rule inversion gives a non-ground T discriminated by Hgrd. Total addition: ~30 lines in Semantics_L1.v + ~12 lines in Syntax.v. Coqc 8.18.0 clean across all 10 .v files. Zero new admits/axioms. `Semantics.v`/`Typing.v`/`Counterexample.v` untouched. Unblocks Phase 2 (parallel substitution lemma for ground non-linear T1). PR #219."
9+
next_action: "Phase D slice 4 Phase 3 — ship `tfuneff_lambda_retype_l1_m` per `formal/SUBST-LEMMA-GENERALIZATION-DESIGN.md` §'Phase 3'. Retype lemma for TFunEff-typed lambdas (`ELam T0 e` typed at `TFunEff T1 T2 R_in R_out`) under the side condition `forall r, In r R' -> In r R_in`. Extend the Phase 2 substitution lemma to cover `T1 = TFunEff …` lambdas as substituends. The TFun (non-Eff) lambda case has body-R-rigidity (same gap as legacy preservation_l1 slice 4b) — explicitly OUT OF SCOPE for Phase 3 per design doc §'Open design questions' #2 (recommended: TFunEff only). After Phase 3, Phase 4 closes `preservation_l2`'s `T_App_L2_Eff` β-case for: (a) linear T1 via existing `subst_typing_gen_l1_m`; (b) ground non-linear T1 via Phase 2's `subst_typing_gen_l1_m_ground_nonlinear`; (c) TFunEff non-linear T1 via Phase 3; (d) compound non-linear T1 deferred to Phase 5. Anti-patterns to refuse (per CLAUDE.md owner directive): no `Admitted` to close cases; no touching `Semantics.v`/`Typing.v`/`Counterexample.v`; no closure of residual `Semantics_L1.v` admits via this work — strictly NEW infrastructure orthogonal to legacy. Coqc 8.18.0 is the only authority."
10+
last_action: "Phase D slice 4 Phase 2 LANDED (2026-05-30): `subst_typing_gen_l1_m_ground_nonlinear` parallel substitution lemma added to `formal/Semantics_L1.v` mirroring `subst_typing_gen_l1_m`'s 28+ case structure for `is_ground_nonlinear_ty T1 = true`. Three key divergences from the linear lemma: (i) T_Var_Lin_L1 i=k0 → exfalso via `is_linear_ty Tsub = false` vs rule's premise `is_linear_ty T = true`; (ii) T_Var_Unr_L1 i=k0 → CONSTRUCTIVE case applying `ground_nonlinear_retype_l1_m` to lift Hv_type from Linear to active modality m; (iii) compound rules use `ground_nonlinear_retype_l1_m` directly (no `linear_value_is_loc_l1` / `loc_retype_at_R_l1_m` / `region_liveness_at_split_l1_gen` pipeline — ground retype takes any R, any G, any m). Phase 1's `ground_nonlinear_retype_l1_m` generalised in this PR to (m → m', R → R', G → G')-polymorphic (Phase 1 ships m-monomorphic R-only retype; Phase 2 needs the cross-modality cross-context bridge). New helper `ground_nonlinear_value_shift_id_l1` proves `shift c d v = v` for ground non-linear values; used to rewrite the `shift 0 1 vv` introduced by `subst`'s descent through term binders in T_Let_L1 / T_LetLin_L1 / T_Lam_L1_* (4 lambda rules) / T_Case_L1_* (2 case rules). Coqc 8.18.0 clean rebuild across all 10 .v files. Zero new admits/axioms. `Semantics.v`/`Typing.v`/`Counterexample.v` untouched. Phase 2 unblocks Phase 3 (TFunEff lambda retype) and Phase 4 (close preservation_l2 β-case for ground non-linear T1). Sibling-lemma approach preserves ~30 Qed downstreams of `subst_typing_gen_l1_m`."
1111
updated: 2026-05-30T00:00:00Z
1212

1313
@directive(source="owner", date="2026-05-27", canonical="CLAUDE.md"):

formal/Semantics_L1.v

Lines changed: 320 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,13 +1197,13 @@ Proof. intros. apply T_Loc_L1. assumption. Qed.
11971197
[has_type_l1] judgment carrying the modality parameter [m]. It
11981198
does not extend or patch [Semantics.v]. *)
11991199
Lemma ground_nonlinear_retype_l1_m :
1200-
forall (m : Modality) (R R' : region_env) (G : ctx) (v : expr) (T : ty),
1200+
forall (m m' : Modality) (R R' : region_env) (G G' : ctx) (v : expr) (T : ty),
12011201
is_value v ->
12021202
is_ground_nonlinear_ty T = true ->
12031203
has_type_l1 m R G v T R G ->
1204-
has_type_l1 m R' G v T R' G.
1204+
has_type_l1 m' R' G' v T R' G'.
12051205
Proof.
1206-
intros m R R' G v T Hval Hgrd Ht.
1206+
intros m m' R R' G G' v T Hval Hgrd Ht.
12071207
destruct Hval as
12081208
[ | b | n
12091209
| T0 e0 | v1 v2 Hv1 Hv2
@@ -1217,6 +1217,37 @@ Proof.
12171217
- (* v = EI32 n, T = TBase TI32 *) apply T_I32_L1.
12181218
Qed.
12191219

1220+
(** Ground non-linear values are closed terms — they contain no
1221+
de Bruijn variables, so de Bruijn [shift] is the identity on them.
1222+
1223+
Used by [subst_typing_gen_l1_m_ground_nonlinear] under term-binder
1224+
cases (T_Let_L1, T_LetLin_L1, the four T_Lam_L1 lambda rules, and
1225+
the two T_Case_L1 case rules), where the operational substitution
1226+
introduces a [shift 0 1 vv] around the substituted value when
1227+
descending through a binder. For ground non-linear [vv]
1228+
(EUnit / EBool b / EI32 n) the shift is definitionally the
1229+
identity; this lemma packages that observation so the rewrite can
1230+
fire after canonical-form extraction.
1231+
1232+
Refs [formal/SUBST-LEMMA-GENERALIZATION-DESIGN.md] Phase 2. *)
1233+
Lemma ground_nonlinear_value_shift_id_l1 :
1234+
forall m R G v T c d,
1235+
is_value v ->
1236+
is_ground_nonlinear_ty T = true ->
1237+
has_type_l1 m R G v T R G ->
1238+
shift c d v = v.
1239+
Proof.
1240+
intros m R G v T c d Hval Hgrd Ht.
1241+
destruct Hval as
1242+
[ | b | n
1243+
| T0 e0 | v1 v2 Hv1 Hv2
1244+
| T0 v0 Hv0 | T0 v0 Hv0
1245+
| l r
1246+
| v0 Hv0
1247+
| T0 v0 Hv0 ];
1248+
inversion Ht; subst; try discriminate Hgrd; reflexivity.
1249+
Qed.
1250+
12201251
(** Narrower axiom (region-liveness at compound-rule split points).
12211252
12221253
Given a well-typed sub-derivation [R; G |=L1 e1 : T1 -| R1; G']
@@ -1695,6 +1726,292 @@ Proof.
16951726
- eapply T_Observe_L1. eapply IHHtype; eassumption.
16961727
Qed.
16971728

1729+
(** Parallel substitution lemma for ground non-linear [T1].
1730+
1731+
Phase D slice 4 Phase 2 per [formal/SUBST-LEMMA-GENERALIZATION-DESIGN.md].
1732+
Mirrors [subst_typing_gen_l1_m] structurally; the case-internal
1733+
reasoning differs in three places:
1734+
1735+
- [T_Var_Lin_L1] with [i = k0]: the rule's [is_linear_ty T = true]
1736+
premise contradicts [Hgrd : is_ground_nonlinear_ty Tsub = true]
1737+
(since [is_ground_nonlinear_ty Tsub = true ->
1738+
is_linear_ty Tsub = false] by inspection). Discharged via
1739+
[exfalso].
1740+
- [T_Var_Unr_L1] with [i = k0]: CONSTRUCTIVE here (the symmetric
1741+
case in the linear lemma is the exfalso branch). The substituted
1742+
value [vv] typed at [Linear] is lifted to the active modality [m]
1743+
via [ground_nonlinear_retype_l1_m] (Phase 1).
1744+
- Compound rules: [ground_nonlinear_retype_l1_m] replaces the
1745+
[linear_value_is_loc_l1] + [loc_retype_at_R_l1_m] +
1746+
[region_liveness_at_split_l1_gen] pipeline. The retype takes any
1747+
[R'], so no liveness side-condition is required.
1748+
1749+
Ships as a SIBLING lemma rather than folding case-split into the
1750+
existing [subst_typing_gen_l1_m] to preserve the ~30 [Qed]
1751+
downstreams. *)
1752+
Lemma subst_typing_gen_l1_m_ground_nonlinear :
1753+
forall m R Gin e T R' Gout,
1754+
has_type_l1 m R Gin e T R' Gout ->
1755+
forall k T1 v u_in,
1756+
nth_error Gin k = Some (T1, u_in) ->
1757+
is_value v ->
1758+
is_ground_nonlinear_ty T1 = true ->
1759+
R; remove_at k Gin |=L1 v : T1 -| R; remove_at k Gin ->
1760+
forall u_out,
1761+
nth_error Gout k = Some (T1, u_out) ->
1762+
has_type_l1 m R (remove_at k Gin) (subst k v e) T R' (remove_at k Gout).
1763+
Proof.
1764+
intros m R Gin e T R' Gout Htype.
1765+
induction Htype; intros k0 Tsub vv u_in Hk_in Hval Hgrd Hv_type u_out Hk_out; simpl.
1766+
1767+
(* T_Unit_L1, T_Bool_L1, T_I32_L1 *)
1768+
1-3: (assert (u_out = u_in) by congruence; subst; constructor).
1769+
1770+
(* T_Var_Lin_L1 *)
1771+
- destruct (Nat.eq_dec i k0) as [->|Hne].
1772+
+ (* i = k0: rule's [is_linear_ty T = true] contradicts
1773+
[is_ground_nonlinear_ty Tsub = true] *)
1774+
exfalso.
1775+
assert (T = Tsub) by (unfold ctx_lookup in H; congruence). subst T.
1776+
destruct Tsub as [b| | | | | | | | |]; try discriminate Hgrd.
1777+
destruct b; try discriminate Hgrd; discriminate H0.
1778+
+ rewrite (proj2 (Nat.eqb_neq i k0) Hne).
1779+
destruct (Nat.ltb_spec k0 i) as [Hlt|Hge].
1780+
* assert (Hrw: remove_at k0 (ctx_mark_used G i) =
1781+
ctx_mark_used (remove_at k0 G) (i - 1)).
1782+
{ replace i with (S (i - 1)) at 1 by lia.
1783+
apply remove_at_ctx_mark_used_gt. lia. }
1784+
rewrite Hrw.
1785+
eapply T_Var_Lin_L1.
1786+
-- unfold ctx_lookup. rewrite nth_error_remove_at_ge by lia.
1787+
replace (S (i - 1)) with i by lia.
1788+
unfold ctx_lookup in H. exact H.
1789+
-- exact H0.
1790+
* assert (i < k0) by lia.
1791+
rewrite remove_at_ctx_mark_used_lt by lia.
1792+
eapply T_Var_Lin_L1.
1793+
-- unfold ctx_lookup. rewrite nth_error_remove_at_lt by lia.
1794+
unfold ctx_lookup in H. exact H.
1795+
-- exact H0.
1796+
1797+
(* T_Var_Unr_L1 *)
1798+
- destruct (Nat.eq_dec i k0) as [->|Hne].
1799+
+ (* i = k0: CONSTRUCTIVE case for ground non-linear substitution.
1800+
Rule output context equals input — no marking. *)
1801+
rewrite Nat.eqb_refl.
1802+
assert (T = Tsub) by (unfold ctx_lookup in H; congruence). subst T.
1803+
assert (u_out = u_in) by congruence; subst u_out.
1804+
eapply ground_nonlinear_retype_l1_m; eauto.
1805+
+ rewrite (proj2 (Nat.eqb_neq i k0) Hne).
1806+
destruct (Nat.ltb_spec k0 i) as [Hlt|Hge].
1807+
* eapply T_Var_Unr_L1.
1808+
-- unfold ctx_lookup. rewrite nth_error_remove_at_ge by lia.
1809+
replace (S (i - 1)) with i by lia.
1810+
unfold ctx_lookup in H. exact H.
1811+
-- exact H0.
1812+
* assert (i < k0) by lia. eapply T_Var_Unr_L1.
1813+
-- unfold ctx_lookup. rewrite nth_error_remove_at_lt by lia.
1814+
unfold ctx_lookup in H. exact H.
1815+
-- exact H0.
1816+
1817+
(* T_Loc_L1 *)
1818+
- assert (u_out = u_in) by congruence; subst. constructor. assumption.
1819+
(* T_StringNew_L1 *)
1820+
- assert (u_out = u_in) by congruence; subst. constructor. assumption.
1821+
1822+
(* T_StringConcat_L1 *)
1823+
- destruct (output_shape_at_l1 _ _ _ _ _ _ _ _ _ _ Htype1 Hk_in) as [u_mid Hu_mid].
1824+
eapply T_StringConcat_L1.
1825+
+ eapply IHHtype1; eassumption.
1826+
+ eapply IHHtype2; try eassumption; try reflexivity.
1827+
eapply ground_nonlinear_retype_l1_m; eauto.
1828+
1829+
(* T_StringLen_L1 *)
1830+
- eapply T_StringLen_L1. eapply IHHtype; eassumption.
1831+
1832+
(* T_Let_L1 *)
1833+
- destruct (output_shape_at_l1 _ _ _ _ _ _ _ _ _ _ Htype1 Hk_in) as [u_mid Hu_mid].
1834+
eapply T_Let_L1.
1835+
+ eapply IHHtype1; eassumption.
1836+
+ rewrite (ground_nonlinear_value_shift_id_l1 _ _ _ _ _ 0 1 Hval Hgrd Hv_type).
1837+
eapply (IHHtype2 (S k0) Tsub vv u_mid);
1838+
simpl; try eassumption; try reflexivity.
1839+
eapply ground_nonlinear_retype_l1_m; eassumption.
1840+
1841+
(* T_LetLin_L1 *)
1842+
- destruct (output_shape_at_l1 _ _ _ _ _ _ _ _ _ _ Htype1 Hk_in) as [u_mid Hu_mid].
1843+
eapply T_LetLin_L1; [exact H | |].
1844+
+ eapply IHHtype1; eassumption.
1845+
+ rewrite (ground_nonlinear_value_shift_id_l1 _ _ _ _ _ 0 1 Hval Hgrd Hv_type).
1846+
eapply (IHHtype2 (S k0) Tsub vv u_mid);
1847+
simpl; try eassumption; try reflexivity.
1848+
eapply ground_nonlinear_retype_l1_m; eassumption.
1849+
1850+
(* T_Lam_L1_Linear: body's R = outer R; ground value retypes trivially. *)
1851+
- assert (u_out = u_in) by congruence; subst.
1852+
eapply T_Lam_L1_Linear.
1853+
rewrite (ground_nonlinear_value_shift_id_l1 _ _ _ _ _ 0 1 Hval Hgrd Hv_type).
1854+
eapply (IHHtype (S k0) Tsub vv u_in);
1855+
simpl; try eassumption; try reflexivity.
1856+
eapply ground_nonlinear_retype_l1_m; eassumption.
1857+
1858+
(* T_Lam_L1_Affine *)
1859+
- assert (u_out = u_in) by congruence; subst.
1860+
eapply T_Lam_L1_Affine.
1861+
rewrite (ground_nonlinear_value_shift_id_l1 _ _ _ _ _ 0 1 Hval Hgrd Hv_type).
1862+
eapply (IHHtype (S k0) Tsub vv u_in);
1863+
simpl; try eassumption; try reflexivity.
1864+
eapply ground_nonlinear_retype_l1_m; eassumption.
1865+
1866+
(* T_Lam_L1_Linear_Eff — body's R = R_in (independent of outer R);
1867+
ground value retypes to ANY R, so no [R -> R_in] side-condition
1868+
is needed. *)
1869+
- assert (u_out = u_in) by congruence; subst.
1870+
eapply T_Lam_L1_Linear_Eff; [exact H |].
1871+
rewrite (ground_nonlinear_value_shift_id_l1 _ _ _ _ _ 0 1 Hval Hgrd Hv_type).
1872+
eapply (IHHtype (S k0) Tsub vv u_in);
1873+
simpl; try eassumption; try reflexivity.
1874+
eapply ground_nonlinear_retype_l1_m; eassumption.
1875+
1876+
(* T_Lam_L1_Affine_Eff *)
1877+
- assert (u_out = u_in) by congruence; subst.
1878+
eapply T_Lam_L1_Affine_Eff; [exact H |].
1879+
rewrite (ground_nonlinear_value_shift_id_l1 _ _ _ _ _ 0 1 Hval Hgrd Hv_type).
1880+
eapply (IHHtype (S k0) Tsub vv u_in);
1881+
simpl; try eassumption; try reflexivity.
1882+
eapply ground_nonlinear_retype_l1_m; eassumption.
1883+
1884+
(* T_App_L1 *)
1885+
- destruct (output_shape_at_l1 _ _ _ _ _ _ _ _ _ _ Htype1 Hk_in) as [u_mid Hu_mid].
1886+
eapply T_App_L1.
1887+
+ eapply IHHtype1; eassumption.
1888+
+ eapply IHHtype2; try eassumption; try reflexivity.
1889+
eapply ground_nonlinear_retype_l1_m; eauto.
1890+
1891+
(* T_Pair_L1 *)
1892+
- destruct (output_shape_at_l1 _ _ _ _ _ _ _ _ _ _ Htype1 Hk_in) as [u_mid Hu_mid].
1893+
eapply T_Pair_L1.
1894+
+ eapply IHHtype1; eassumption.
1895+
+ eapply IHHtype2; try eassumption; try reflexivity.
1896+
eapply ground_nonlinear_retype_l1_m; eauto.
1897+
1898+
(* T_Fst_L1 *)
1899+
- eapply T_Fst_L1; [eapply IHHtype; eassumption | assumption].
1900+
1901+
(* T_Snd_L1 *)
1902+
- eapply T_Snd_L1; [eapply IHHtype; eassumption | assumption].
1903+
1904+
(* T_Inl_L1 *)
1905+
- eapply T_Inl_L1. eapply IHHtype; eassumption.
1906+
1907+
(* T_Inr_L1 *)
1908+
- eapply T_Inr_L1. eapply IHHtype; eassumption.
1909+
1910+
(* T_Case_L1_Linear *)
1911+
- destruct (output_shape_at_l1 _ _ _ _ _ _ _ _ _ _ Htype1 Hk_in) as [u_mid Hu_mid].
1912+
eapply T_Case_L1_Linear.
1913+
+ eapply IHHtype1; eassumption.
1914+
+ rewrite (ground_nonlinear_value_shift_id_l1 _ _ _ _ _ 0 1 Hval Hgrd Hv_type).
1915+
eapply (IHHtype2 (S k0) Tsub vv u_mid);
1916+
simpl; try eassumption; try reflexivity.
1917+
eapply ground_nonlinear_retype_l1_m; eassumption.
1918+
+ rewrite (ground_nonlinear_value_shift_id_l1 _ _ _ _ _ 0 1 Hval Hgrd Hv_type).
1919+
eapply (IHHtype3 (S k0) Tsub vv u_mid);
1920+
simpl; try eassumption; try reflexivity.
1921+
eapply ground_nonlinear_retype_l1_m; eassumption.
1922+
1923+
(* T_Case_L1_Affine *)
1924+
- destruct (output_shape_at_l1 _ _ _ _ _ _ _ _ _ _ Htype1 Hk_in) as [u_mid Hu_mid].
1925+
eapply T_Case_L1_Affine.
1926+
+ eapply IHHtype1; eassumption.
1927+
+ rewrite (ground_nonlinear_value_shift_id_l1 _ _ _ _ _ 0 1 Hval Hgrd Hv_type).
1928+
eapply (IHHtype2 (S k0) Tsub vv u_mid);
1929+
simpl; try eassumption; try reflexivity.
1930+
eapply ground_nonlinear_retype_l1_m; eassumption.
1931+
+ rewrite (ground_nonlinear_value_shift_id_l1 _ _ _ _ _ 0 1 Hval Hgrd Hv_type).
1932+
eapply (IHHtype3 (S k0) Tsub vv u_mid);
1933+
simpl; try eassumption; try reflexivity.
1934+
eapply ground_nonlinear_retype_l1_m; eassumption.
1935+
1936+
(* T_If_L1_Linear *)
1937+
- destruct (output_shape_at_l1 _ _ _ _ _ _ _ _ _ _ Htype1 Hk_in) as [u_mid Hu_mid].
1938+
eapply T_If_L1_Linear.
1939+
+ eapply IHHtype1; eassumption.
1940+
+ eapply IHHtype2; try eassumption; try reflexivity.
1941+
eapply ground_nonlinear_retype_l1_m; eauto.
1942+
+ eapply IHHtype3; try eassumption; try reflexivity.
1943+
eapply ground_nonlinear_retype_l1_m; eauto.
1944+
1945+
(* T_If_L1_Affine *)
1946+
- destruct (output_shape_at_l1 _ _ _ _ _ _ _ _ _ _ Htype1 Hk_in) as [u_mid Hu_mid].
1947+
eapply T_If_L1_Affine.
1948+
+ eapply IHHtype1; eassumption.
1949+
+ eapply IHHtype2; try eassumption; try reflexivity.
1950+
eapply ground_nonlinear_retype_l1_m; eauto.
1951+
+ eapply IHHtype3; try eassumption; try reflexivity.
1952+
eapply ground_nonlinear_retype_l1_m; eauto.
1953+
1954+
(* T_Region_L1: body's R = [r :: R]; ground retypes trivially. *)
1955+
- eapply T_Region_L1; [exact H | exact H0 | exact H1 |].
1956+
eapply IHHtype; try eassumption; try reflexivity.
1957+
eapply ground_nonlinear_retype_l1_m; eauto.
1958+
1959+
(* T_Region_Active_L1 *)
1960+
- eapply T_Region_Active_L1; [exact H | exact H0 | exact H1 |].
1961+
eapply IHHtype; try eassumption; try reflexivity.
1962+
1963+
(* T_Region_L1_Echo *)
1964+
- eapply T_Region_L1_Echo; [exact H | exact H0 | exact H1 |].
1965+
eapply IHHtype; try eassumption; try reflexivity.
1966+
eapply ground_nonlinear_retype_l1_m; eauto.
1967+
1968+
(* T_Region_Active_L1_Echo *)
1969+
- eapply T_Region_Active_L1_Echo; [exact H | exact H0 | exact H1 |].
1970+
eapply IHHtype; try eassumption; try reflexivity.
1971+
1972+
(* T_Borrow_L1: EBorrow (EVar i) *)
1973+
- destruct (Nat.eq_dec i k0) as [->|Hne].
1974+
+ simpl. rewrite Nat.eqb_refl.
1975+
assert (T = Tsub) by (unfold ctx_lookup in H; congruence); subst T.
1976+
assert (u_out = u_in) by congruence; subst.
1977+
eapply T_Borrow_Val_L1.
1978+
* (* vv is a ground value, hence a value *) assumption.
1979+
* eapply ground_nonlinear_retype_l1_m; eauto.
1980+
+ simpl. rewrite (proj2 (Nat.eqb_neq i k0) Hne).
1981+
assert (u_out = u_in) by congruence; subst.
1982+
destruct (Nat.ltb_spec k0 i) as [Hlt|Hge].
1983+
* eapply T_Borrow_L1. unfold ctx_lookup.
1984+
rewrite nth_error_remove_at_ge by lia.
1985+
replace (S (i - 1)) with i by lia.
1986+
unfold ctx_lookup in H. exact H.
1987+
* assert (i < k0) by lia. eapply T_Borrow_L1. unfold ctx_lookup.
1988+
rewrite nth_error_remove_at_lt by lia.
1989+
unfold ctx_lookup in H. exact H.
1990+
1991+
(* T_Borrow_Val_L1 *)
1992+
- assert (u_out = u_in) by congruence; subst.
1993+
eapply T_Borrow_Val_L1.
1994+
+ apply subst_preserves_value. assumption.
1995+
+ eapply IHHtype; eassumption.
1996+
1997+
(* T_Drop_L1 *)
1998+
- eapply T_Drop_L1; [exact H |]. eapply IHHtype; eassumption.
1999+
2000+
(* T_Drop_L1_Echo *)
2001+
- eapply T_Drop_L1_Echo; [exact H |]. eapply IHHtype; eassumption.
2002+
2003+
(* T_Copy_L1 *)
2004+
- eapply T_Copy_L1; [exact H |]. eapply IHHtype; eassumption.
2005+
2006+
(* T_Echo_L1 *)
2007+
- eapply T_Echo_L1.
2008+
+ apply subst_preserves_value. assumption.
2009+
+ eapply IHHtype; eassumption.
2010+
2011+
(* T_Observe_L1 *)
2012+
- eapply T_Observe_L1. eapply IHHtype; eassumption.
2013+
Qed.
2014+
16982015
(** Linear-specialised wrapper preserving the original signature for
16992016
[subst_preserves_typing_l1] and [preservation_l1]. *)
17002017
Lemma subst_typing_gen_l1 :

0 commit comments

Comments
 (0)