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>
126 lines
6.2 KiB
Text
126 lines
6.2 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
|
|
|
|
/-- `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
|