Some checks are pending
Lean Action CI / build (push) Waiting to run
Restructure to engine-only contents. Application code (Topolei.*
namespace, canvas-rs / render Rust crates, Main / ProbeTest, naga IR
pipeline, Selection / Subobject / Trace / Obs.Ctx hypothesis stack,
cells-spec / HYPOTHESES / STATUS / NAGA_IR_PLAN docs) moves to the
sibling repo max/topolei.
What moved:
- `Topolei/Cubical/*.lean` (22 files) → `CubicalTransport/*.lean`
with namespace `Topolei.Cubical.*` renamed to `CubicalTransport.*`.
Fully-qualified test types `TopoleiCubical{FFI,Property}Test` →
`CubicalTransport{FFI,Property}Test` for consistency.
- New root file `CubicalTransport.lean` re-exporting all 22 modules.
- Lakefile: package `cubicalTransport`; lib `CubicalTransport`; only
`cubical-test` and `cubical-bench` exes (no GPU link path).
The split criterion: anything an AI shortcut could break that would
cascade-corrupt downstream proofs lives here. Anything that would
only break the application stays in the topolei interface repo.
cubical-test passes 62/62 (smoke + properties) on the renamed engine.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
153 lines
6.8 KiB
Text
153 lines
6.8 KiB
Text
/-
|
||
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]
|