/- Topolei.Cubical.Transport ========================= Value-level transport (cells-spec §5.5, Phase 1 Weeks 3–4). `vTransp i A φ v` reduces `transp^i A φ v` at the value level. Reducing cases (in match order, highest priority first): 1. **φ = .top** — full face — return `v` unchanged. Evaluator-level analogue of axiom `transp_id` (T1). 2. **`CType.dimAbsent i A = true`** — line is constant — return `v` unchanged. Evaluator-level analogue of `transp_const_id` (T2). Covers `univ`, fully-constant `pi`, fully-constant `path`. 3. **`A = pi domA codA`** — produce a `vTranspFun i domA codA φ v` closure. This is the **full CCHM Π rule** — when the closure is later applied to an argument, `vApp` inversely transports the argument through `domA` and forward-transports the result through `codA`. Both constant-domain and varying-domain lines are handled by the same constructor; `vTranspInv` degenerates to identity in the constant-domain case via `CType.substDimExpr_of_absent` + T2, so no special-case logic is needed at this level. 4. **Otherwise** — stuck. Produce `vneu (.ntransp i A φ v)`. Deferred to later passes: · Σ case — `CType` has no Σ yet. · Path case — Week 4, alongside homogeneous composition. vTransp is a `partial def` for the same reason as `eval`. Its reduction equations are stated as axioms below. `vTranspInv` is a *total `def`* because it is a thin wrapper that delegates to `vTransp` after line reversal. -/ import CubicalTransport.Value import CubicalTransport.DimLine -- for CType.dimAbsent and substDimExpr -- ── Rust FFI declaration (Phase C.2) ────────────────────────────────────── @[extern "topolei_cubical_vtransp"] opaque vTranspRust (i : DimVar) (A : CType) (φ : FaceFormula) (v : CVal) : CVal /-- Value-level transport. Dispatches in priority order; see file header. -/ @[implemented_by vTranspRust] partial def vTransp (i : DimVar) (A : CType) (φ : FaceFormula) (v : CVal) : CVal := match φ with | .top => v -- (1) T1 at eval level. | _ => if CType.dimAbsent i A then v -- (2) T2 at eval level. else match A with | .pi domA codA => -- (3) Full CCHM Π rule — no specialisation here. The behaviour -- at constant-domain vs. varying-domain is absorbed into the -- later reduction of `vApp` on `vTranspFun`, which calls -- `vTranspInv` on `domA` (identity when `domA` is constant). .vTranspFun i domA codA φ v | _ => -- (4) non-pi stuck (e.g. path with varying endpoints). .vneu (.ntransp i A φ v) /-- **Inverse transport** along the line `(i, A)`: transport `v : A(1)` back to `A(0)`. Implemented as forward transport along the *reversed* line `A[i := inv i]`. Line reversal properties at the endpoints: `A[i := inv i] at 0` = `A at (inv 0)` = `A at 1` `A[i := inv i] at 1` = `A at (inv 1)` = `A at 0` So forward transport along the reversed line takes `A(1) ↦ A(0)`, which is exactly the inverse of forward transport along `A`. -/ def vTranspInv (i : DimVar) (A : CType) (φ : FaceFormula) (v : CVal) : CVal := vTransp i (A.substDimExpr i (.inv (.var i))) φ v /-! ## Reduction axioms and theorems One axiom per reducing match arm of `vTransp`. The arms are disjoint (ordered pattern match), so the axiom set is consistent. -/ /-- (1) Reduction under a full face: transport is identity. -/ axiom vTransp_top (i : DimVar) (A : CType) (v : CVal) : vTransp i A .top v = v /-- (2) Reduction under a constant line. -/ axiom vTransp_const (i : DimVar) (A : CType) (φ : FaceFormula) (v : CVal) (h : CType.dimAbsent i A = true) : vTransp i A φ v = v /-- (3) Π case (full CCHM rule): produces a transported-function closure that stores both domain and codomain. Preconditions: · `φ ≠ .top` — else (1) fires, · `CType.dimAbsent i (.pi domA codA) = false` — else (2) fires. When `dimAbsent i domA = true`, the inverse transport inside the later `vApp` reduction degenerates to identity by `vTranspInv_const` below, recovering the const-domain specialisation. -/ axiom vTransp_pi (i : DimVar) (domA codA : CType) (φ : FaceFormula) (v : CVal) (hφ : φ ≠ .top) (hA : CType.dimAbsent i (.pi domA codA) = false) : vTransp i (.pi domA codA) φ v = .vTranspFun i domA codA φ v /-- (4) Stuck: not face-top, not constant, and not a `.pi`. The third precondition rules out arm (3). -/ axiom vTransp_stuck (i : DimVar) (A : CType) (φ : FaceFormula) (v : CVal) (hφ : φ ≠ .top) (hA : CType.dimAbsent i A = false) (h_not_pi : ∀ domA codA, A ≠ .pi domA codA) : vTransp i A φ v = .vneu (.ntransp i A φ v) -- ── vTranspInv on constant domain ──────────────────────────────────────────── /-- Inverse transport along a line whose body is absent from `i` is the identity. Proof: the reversed line `A[i := inv i] = A` when `i ∉ A` (by `CType.substDimExpr_of_absent`), so the outer `vTransp` call has a constant line and reduces via T2 to `v`. This lemma is what makes the unified `vTranspFun` constructor degenerate correctly when the domain is constant. -/ theorem vTranspInv_const (i : DimVar) (A : CType) (φ : FaceFormula) (v : CVal) (h : CType.dimAbsent i A = true) : vTranspInv i A φ v = v := by -- `vTranspInv` unfolds to `vTransp i (A[i := inv i]) φ v`. unfold vTranspInv -- Line reversal is a no-op on constant-in-`i` types. rw [CType.substDimExpr_of_absent i _ A h] -- T2 on the (unchanged) constant line. exact vTransp_const i A φ v h /-- Inverse transport under a full face is identity — direct consequence of T1 composed with reversal. -/ theorem vTranspInv_top (i : DimVar) (A : CType) (v : CVal) : vTranspInv i A .top v = v := by unfold vTranspInv exact vTransp_top i _ v -- ── Convenience wrappers ────────────────────────────────────────────────────── /-- Transport along a `DimLine` with an already-evaluated argument. Unpacks the line's binder and body and dispatches through `vTransp`. -/ def vTranspLine (L : DimLine) (φ : FaceFormula) (v : CVal) : CVal := vTransp L.binder L.body φ v @[simp] theorem vTranspLine_top (L : DimLine) (v : CVal) : vTranspLine L .top v = v := by simp [vTranspLine, vTransp_top] theorem vTranspLine_const (L : DimLine) (φ : FaceFormula) (v : CVal) (h : CType.dimAbsent L.binder L.body = true) : vTranspLine L φ v = v := by simp [vTranspLine, vTransp_const _ _ _ _ h]