cubical-transport-hott-lean4/Topolei/Canvas.lean
Maximus Gorog c2e3ecb3e3
Some checks are pending
Lean Action CI / build (push) Waiting to run
Initial commit: topolei — cubical-transport HoTT in Lean 4 + Rust FFI
Implements the cells-spec vision: a computation space that preserves
auditability, correctness, interactivity. Phase 1 (Lean kernel +
naga-IR Rust backend) is closed; foundation hypothesis stack
(Selection H1+H2, Subobject H3, Trace H5, Obs.Ctx C2, Cubical.Trace)
landed.

Highlights:
- Cubical-HoTT syntax + value/eval/readback in Lean
- naga-IR pipeline (no GLSL string crosses FFI; 17/17 probes pass)
- Honesty audit: every non-transport (sealed cells, vertex shader,
  Y-flip, presentation conventions) is documented as such
- Polymorphic Trace α as free monoid; Cubical.Trace gives
  CTerm → Trace CTerm by structural fold (homomorphism = definition)
- Selection as Huet zipper; Subobject as Boolean algebra over WCell
- All theorems proven; the proof IS the implementation

See STATUS.md for the resume guide.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 20:40:45 -06:00

46 lines
2 KiB
Text

import Topolei.EML.Path
/-!
Topolei.Canvas
==============
Lean bindings to the live wgpu canvas. Both entry points take an
`EMLPath` (a structured cubical-1-cell) and a fixed `pathParam : Float`,
not a shader-source string and not a time-driven driver. The
fragment shader is built directly as a `naga::Module` on the Rust
side from the Lean inductive walk; the rendering is **static** —
every frame is the 1-cell's fiber at exactly `pathParam`.
## Why no animation curve?
An earlier iteration animated `pathParam` host-side via a sine
sweep of `u_time`. That sweep is not a cubical transport — it's a
free-standing time-to-parameter function chosen for visual effect.
Driving rendering by something that is not itself a transport
violates the cells-spec discipline that "every continuous function
in the visible pipeline is a transport". The animated form belongs
to a 2-cell (a homotopy of 1-cells parameterised by a second
interval); we don't have 2-cell infrastructure yet, so we render
fixed fibers and leave time-driven motion for the 2-cell pass.
See `NAGA_IR_PLAN.md` for the IR-builder plan; `compileEMLPath_correct`
in `Topolei.GPU.Spec` is the contract the Rust IR builder satisfies.
-/
/-- Live render of one fiber of an `EMLPath`. `pathParam` chooses
the fiber; the rendering is static (the same fiber persists for
the lifetime of the window). -/
@[extern "topolei_run_path"]
opaque canvasRunPath
(path : @& EMLPath) (pathParam : Float)
(width height : UInt32) (title : @& String) : IO Unit
/-- Two-panel side-by-side variant: `pathL` rendered at fiber `ppL`
on the left, `pathR` at fiber `ppR` on the right. Each panel has
its own uniform buffer, so the two fibers are independent — pass
distinct `ppL`/`ppR` to display two different fibers (e.g. `at0`
vs `at1` of the same 1-cell). -/
@[extern "topolei_run_path2"]
opaque canvasRunPath2
(pathL : @& EMLPath) (ppL : Float)
(pathR : @& EMLPath) (ppR : Float)
(width height : UInt32) (title : @& String) : IO Unit