Some checks are pending
Lean Action CI / build (push) Waiting to run
Typing.lean: minimal-viable typing rules for the three new CTerm
constructors (REL1 first cut; REL2 will refine to dependent
formulations).
- HasType.ctor : .ctor S c params args : .ind S params
(no per-arg premises; runtime enforces)
- HasType.indElim : non-dependent form — motive : .pi (.ind …) C,
result : C; branch coherence checked at eval
- HasType.dimExpr : placeholder typing at .univ (real interval-
typing requires a CType.interval primitive,
deferred to REL2)
HasType.weaken_core extended with the three new arms.
TransportLaws.lean: derived theorems for transport over .ind (T1,
T2, stuck), all reducing to existing axioms (eval_transp_top,
eval_transp_const, eval_transp_nonpath + vTransp_stuck). Pointwise
distribution through ctor args is REL1.1 future work.
CompLaws.lean: derived theorems for composition over .ind (C1, C2,
const-line, stuck) — corollaries of the existing eval_comp_*
axioms. Same REL1.1 deferral for pointwise distribution.
native/cubical/src/subst.rs: critical Rust fix. The previous
fallback `_ => mk_term_var(ctor_field(t, 0))` corrupted the new
TERM_DIMEXPR / TERM_CTOR / TERM_INDELIM tags by extracting field 0
(a CTypeSchema for ctor) and wrapping it as a malformed .var,
causing infinite recursion / OOM in subst-driven paths
(eval_comp_top calls substDim). Proper arms for all three new
tags + cterm_subst_dim_list and cterm_subst_dim_branches helpers.
Unknown-tag fallback now safely returns the input unchanged
instead of synthesising a malformed .var.
FFITest.lean: three new smoke arms exercising T1/T2 transport and
C1 composition over .ind natC. Result: 28/28 smoke + 46/46
properties = 74/74.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
170 lines
8.4 KiB
Text
170 lines
8.4 KiB
Text
/-
|
|
Topolei.Cubical.TransportLaws
|
|
=============================
|
|
Residual step-level axioms for transport: subject reduction (T3) and
|
|
path-line shape preservation (T4).
|
|
|
|
T1 (`transp_id`) and T2 (`transp_const_id`), formerly stated here as
|
|
step-level axioms, are now NbE theorems in `Cubical/Readback.lean`
|
|
(`readback_transp_id` / `readback_transp_const_id`). T5 is now
|
|
covered by an eval-level axiom (`eval_transp_face_congr` in
|
|
`Eval.lean`) and its NbE theorem (`readback_transp_face_congr`); the
|
|
step-level form was unused and removed in Stream B #2b.
|
|
|
|
The Rust backend's discharge obligations for transport reduce to: the
|
|
eval-level axioms in `Eval.lean`, the readback-level axioms in
|
|
`Readback.lean`, and the two residuals below (T3, T4).
|
|
|
|
Why these two residuals stay step-level:
|
|
· T3 / C4 — subject reduction: needs a typing-preservation lemma on
|
|
`eval`/`readback`, which would require a semantic typing relation
|
|
on `CVal` (Stream B #2a, future work).
|
|
· T4 (general case for non-path lines) — vacuous in well-typed code
|
|
(plam at non-path type is a type error), but kept as a syntactic
|
|
fallback. The path-line case is fully NbE-covered via
|
|
`readback_transp_plam_general` in `Readback.lean` (Stream B #2c).
|
|
-/
|
|
|
|
import CubicalTransport.ValueTyping
|
|
|
|
-- ── Subject reduction for transport ──────────────────────────────────────────
|
|
|
|
/-- **T3 (transport subject reduction)** — stepping a well-typed
|
|
transport term preserves the output type.
|
|
|
|
**Now a theorem, not an axiom.** Stage 2.3 (2026-04-23) consolidated
|
|
T3 and C4 into the single `CTerm.step_preserves_type` axiom in
|
|
`ValueTyping.lean`. T3 here is a direct corollary: the typing rule
|
|
`HasType.transp` places `.transp L.binder L.body φ t` at `L.at1`
|
|
given `t : L.at0`, and `step_preserves_type` propagates that through
|
|
step. -/
|
|
theorem transp_step_preserves (Γ : Ctx) (L : DimLine) (φ : FaceFormula) (t : CTerm)
|
|
(ht : HasType Γ t L.at0) :
|
|
HasType Γ (CTerm.step (.transp L.binder L.body φ t)) L.at1 :=
|
|
CTerm.step_preserves_type Γ _ _ (HasType.transp L ht)
|
|
|
|
-- ── Path endpoint typing ──────────────────────────────────────────────────────
|
|
|
|
/-- Applying a path at 0 gives a term of the path's type. -/
|
|
theorem path_zero_typed (Γ : Ctx) (p : CTerm) (A : CType) (a b : CTerm)
|
|
(hp : HasType Γ p (.path A a b)) :
|
|
HasType Γ (.papp p .zero) A :=
|
|
HasType.papp hp
|
|
|
|
/-- Applying a path at 1 gives a term of the path's type. -/
|
|
theorem path_one_typed (Γ : Ctx) (p : CTerm) (A : CType) (a b : CTerm)
|
|
(hp : HasType Γ p (.path A a b)) :
|
|
HasType Γ (.papp p .one) A :=
|
|
HasType.papp hp
|
|
|
|
-- ── Axiom T4: transport of a plam along a path-typed line (constructive) ─────
|
|
--
|
|
-- Stage 4.2 tightening (2026-04-23). The original T4 axiom was
|
|
-- non-constructive (`∃ body'`); Rust implementations needed concrete
|
|
-- witnesses they couldn't extract. The replacement is *path-restricted*
|
|
-- with an explicit body mirroring `readback_vPathTransp_plam` (the
|
|
-- constructive NbE form from Stream B #2c):
|
|
--
|
|
-- `step (transpⁱ (Path A a b) φ (⟨j⟩ body))`
|
|
-- `= ⟨j⟩ (compⁱ A [φ ↦ body, j=0 ↦ a, j=1 ↦ b] body)`
|
|
--
|
|
-- **Why this is tighter.** Any well-typed `plam j body` has a path type
|
|
-- at the line's 0-endpoint (plam introduces only paths). Transport
|
|
-- preserves type, so the line's body must itself be a path type — hence
|
|
-- `L.body = .path A a b`. Non-path lines are vacuous in well-typed
|
|
-- code. Restricting to `.path A a b` loses no generality and gains a
|
|
-- concrete Rust discharge.
|
|
--
|
|
-- **Face-disjointness with the readback NbE form.** Readback's
|
|
-- `vPathTransp` arm produces exactly this body on `.plam j body` input
|
|
-- (path-input readback), so the axiom and the NbE theorem are consistent.
|
|
|
|
/-- Axiom T4 (path-restricted, constructive):
|
|
Transport of `⟨j⟩ body` along a line whose body is a path type
|
|
`path A a b` produces `⟨j⟩` of a CCHM-shaped comp witness. -/
|
|
axiom transp_plam_is_plam_path
|
|
(i : DimVar) (A : CType) (a b : CTerm)
|
|
(φ : FaceFormula) (j : DimVar) (body : CTerm) :
|
|
CTerm.step (.transp i (.path A a b) φ (.plam j body)) =
|
|
.plam j (.compN i A [(φ, body), (.eq0 j, a), (.eq1 j, b)] body)
|
|
|
|
-- ── Derived helpers ──────────────────────────────────────────────────────────
|
|
|
|
/-- The explicit step-reduced body of a path-line-transported plam. -/
|
|
def transp_plam_body_path
|
|
(i : DimVar) (A : CType) (a b : CTerm)
|
|
(φ : FaceFormula) (j : DimVar) (body : CTerm) : CTerm :=
|
|
.compN i A [(φ, body), (.eq0 j, a), (.eq1 j, b)] body
|
|
|
|
-- ── Transport over schema-defined inductive types (REL1) ────────────────────
|
|
-- Inductive instances `.ind S params` are neither `.path` nor `.glue`, so
|
|
-- transport over them flows through the value-level stuck case in the
|
|
-- existing `vTransp_stuck` axiom. These derived theorems make the API
|
|
-- shape explicit for downstream consumers (paideia, topolei).
|
|
--
|
|
-- A future REL1.1 / REL2 refinement will add pointwise distribution: when
|
|
-- the target is a `.ctor S c cParams cArgs`, transport pushes through
|
|
-- the args via per-arg-shape rules. CCHM HIT-transport gives the
|
|
-- explicit formula via comp-shaped fillers; for plain inductives the
|
|
-- distribution is structurally simpler.
|
|
|
|
/-- Transport over a non-trivial line in a schema-defined inductive
|
|
`.ind S params` reduces to a stuck `ntransp` neutral. Derived from
|
|
`eval_transp_nonpath` (`.ind` is not `.path` and not `.glue`) and
|
|
`vTransp_stuck` (`.ind` is not `.pi`). -/
|
|
theorem eval_transp_ind (env : CEnv) (i : DimVar)
|
|
(S : CTypeSchema) (params : List CType) (φ : FaceFormula) (t : CTerm)
|
|
(hφ : φ ≠ .top)
|
|
(hA : CType.dimAbsent i (.ind S params) = false) :
|
|
eval env (.transp i (.ind S params) φ t) =
|
|
.vneu (.ntransp i (.ind S params) φ (eval env t)) := by
|
|
rw [eval_transp_nonpath env i (.ind S params) φ t hφ hA
|
|
(by intro _ _ _ h; nomatch h)
|
|
(by intro _ _ _ _ _ _ _ _ h; nomatch h)]
|
|
exact vTransp_stuck i (.ind S params) φ (eval env t) hφ hA
|
|
(by intro _ _ h; nomatch h)
|
|
|
|
/-- Transport over a constant `.ind` line is the identity (T2 specialised
|
|
to `.ind`). Direct corollary of `eval_transp_const`. -/
|
|
theorem eval_transp_ind_const (env : CEnv) (i : DimVar)
|
|
(S : CTypeSchema) (params : List CType) (φ : FaceFormula) (t : CTerm)
|
|
(hφ : φ ≠ .top)
|
|
(hA : CType.dimAbsent i (.ind S params) = true) :
|
|
eval env (.transp i (.ind S params) φ t) = eval env t :=
|
|
eval_transp_const env i (.ind S params) φ t hφ hA
|
|
|
|
/-- Transport over `.ind` under a full face is the identity (T1
|
|
specialised to `.ind`). -/
|
|
theorem eval_transp_ind_top (env : CEnv) (i : DimVar)
|
|
(S : CTypeSchema) (params : List CType) (t : CTerm) :
|
|
eval env (.transp i (.ind S params) .top t) = eval env t :=
|
|
eval_transp_top env i (.ind S params) t
|
|
|
|
/-- `transp_plam_is_plam_path` restated via the named body. -/
|
|
theorem transp_plam_body_path_eq
|
|
(i : DimVar) (A : CType) (a b : CTerm)
|
|
(φ : FaceFormula) (j : DimVar) (body : CTerm) :
|
|
CTerm.step (.transp i (.path A a b) φ (.plam j body)) =
|
|
.plam j (transp_plam_body_path i A a b φ j body) :=
|
|
transp_plam_is_plam_path i A a b φ j body
|
|
|
|
-- ── Typed transport of a plam on a path-typed line ───────────────────────────
|
|
|
|
/-- Combines T3 subject reduction with T4 shape preservation on the
|
|
path-typed case: a well-typed `plam`-transport produces a well-typed
|
|
`plam`-witness of the explicit body.
|
|
|
|
Parameterised over a DimLine `L` with an explicit `h_path : L.body =
|
|
.path A a b` — lets the caller instantiate against concrete lines
|
|
whether A/a/b vary in `L.binder` or not. -/
|
|
theorem transp_plam_step_typed_path
|
|
(Γ : Ctx) (L : DimLine) (A : CType) (a b : CTerm)
|
|
(h_path : L.body = .path A a b)
|
|
(φ : FaceFormula) (j : DimVar) (body : CTerm)
|
|
(ht : HasType Γ (.plam j body) L.at0) :
|
|
HasType Γ (.plam j (transp_plam_body_path L.binder A a b φ j body))
|
|
L.at1 := by
|
|
have hstep := transp_step_preserves Γ L φ (.plam j body) ht
|
|
-- Rewrite the transport's line-body to the explicit .path form.
|
|
rw [h_path] at hstep
|
|
rwa [transp_plam_body_path_eq] at hstep
|