Some checks are pending
Lean Action CI / build (push) Waiting to run
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>
90 lines
4.1 KiB
Text
90 lines
4.1 KiB
Text
-- EML tree: S → 1 | eml(S, S)
|
||
-- eml(x, y) = exp(x) − ln(y)
|
||
--
|
||
-- Single binary primitive that generates all elementary functions.
|
||
-- (Odrzywolek 2026, arXiv:2603.21852)
|
||
|
||
-- ── Core inductive ────────────────────────────────────────────────────────────
|
||
|
||
inductive EMLExpr where
|
||
| one : EMLExpr
|
||
| var (name : String) : EMLExpr -- free variable resolved in the rendering env
|
||
| eml (l r : EMLExpr) : EMLExpr
|
||
|
||
-- ── Derived forms ─────────────────────────────────────────────────────────────
|
||
|
||
-- exp(x) = eml(x, 1) since exp(x) − ln(1) = exp(x) − 0 = exp(x)
|
||
def EMLExpr.expOf (x : EMLExpr) : EMLExpr := .eml x .one
|
||
|
||
-- ln(x) = eml(1, eml(eml(1, x), 1))
|
||
def EMLExpr.lnOf (x : EMLExpr) : EMLExpr :=
|
||
.eml .one (.eml (.eml .one x) .one)
|
||
|
||
-- ── Plot configuration ────────────────────────────────────────────────────────
|
||
|
||
/-- A path config: an EML expression plus its distinguished path-dimension
|
||
variable. `dimName` is the name that ranges over `{0, 1}` when the
|
||
config is interpreted as an `EMLPath` (see `EML/Path.lean`'s
|
||
`PlotConfig.toEMLPath`). When `dimName` does not occur in `expr`,
|
||
the path is *constant* (its value is the same at both endpoints);
|
||
when it does, the path is genuinely parametric. -/
|
||
structure PlotConfig where
|
||
expr : EMLExpr
|
||
dimName : String := "t"
|
||
|
||
-- ── Named demo expressions (probe test fixtures) ─────────────────────────────
|
||
|
||
-- exp(x): depth-1 EML tree, one node.
|
||
def plotExp : PlotConfig := {
|
||
expr := EMLExpr.expOf (.var "px")
|
||
}
|
||
|
||
-- ln(x): depth-3 EML tree, three nodes.
|
||
--
|
||
-- Historical note: an earlier `plotLn` used the variable name
|
||
-- `"max(px, 0.001)"` to clamp negative inputs on the GPU side. That
|
||
-- made the GPU shader evaluate `max(px, 0.001)` as a GLSL expression
|
||
-- but left Lean's `shaderVar` hitting the fallback `0.0` — the two
|
||
-- sides disagreed on the semantic of the variable. The probe test
|
||
-- surfaced the divergence; the fix is to use a real variable `px`
|
||
-- and accept that `ln` of negative `px` produces `NaN` on both sides
|
||
-- (the two sides agree, which is what `render_faithful` cares about).
|
||
def plotLn : PlotConfig := {
|
||
expr := EMLExpr.lnOf (.var "px")
|
||
}
|
||
|
||
-- ── Continuous-homotopy demo: a genuinely parametric path ────────────────────
|
||
-- `exp(px) − t` translates the exponential curve down by `t`. At `t=0`
|
||
-- the curve is `y = exp(x)`; at `t=1` it's `y = exp(x) − 1`; in between it
|
||
-- smoothly slides. EML-expressible because `exp(px) - log(exp(t))` reduces
|
||
-- (via `log ∘ exp = id`) to `exp(px) - t`; body is
|
||
-- `eml(var "px", eml(var "t", one))`.
|
||
|
||
def plotTransp : PlotConfig := {
|
||
expr := .eml (.var "px") (.eml (.var "t") .one)
|
||
dimName := "t"
|
||
}
|
||
|
||
-- ── Clean fibers in [0, 1] for greyscale demos ──────────────────────────────
|
||
-- These bodies are picked specifically so their image lies in `[0, 1]`,
|
||
-- matching the framebuffer's natural display range. Each is a 1-cell;
|
||
-- their shape under different `pathParam` values shows the transport
|
||
-- in action with no clamping artifacts.
|
||
|
||
/-- The 1-cell whose body IS the dim variable: at `pathParam = c` every
|
||
pixel evaluates to `c`. Different fibers display as solid-color
|
||
panels with brightness equal to the fiber's parameter.
|
||
`at0 = solid black`, `at1 = solid white`, `mid = solid 50% grey`. -/
|
||
def plotT : PlotConfig := {
|
||
expr := .var "t"
|
||
dimName := "t"
|
||
}
|
||
|
||
/-- The 1-cell whose body is `px`: image is the horizontal coordinate
|
||
itself, a black-to-white left-to-right gradient. Constant
|
||
1-cell (no `t` dependence) — every fiber is the same gradient.
|
||
Useful as a sanity check: fibers should NOT differ. -/
|
||
def plotPx : PlotConfig := {
|
||
expr := .var "px"
|
||
dimName := "t"
|
||
}
|