cubical-transport-hott-lean4/CubicalTransport/TransportLaws.lean
Maximus Gorog 31d19f655e
Some checks are pending
Lean Action CI / build (push) Waiting to run
Split: engine = cubical-transport HoTT only
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>
2026-04-27 21:35:01 -06:00

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