cubical-transport-hott-lean4/CubicalTransport/ValueTyping.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

133 lines
5.9 KiB
Text

/-
Topolei.Cubical.ValueTyping
===========================
Semantic typing on values (Stream B #2a, Stage 2.3).
This module states the *semantic* typing relation on `CVal` / `CNeu`
needed to close the last two step-level residuals (T3 transport and
C4 composition subject reduction). The relation is declarative —
fully inductive definition is future Lean-discharge work; the
important structural fact is that its three preservation obligations
(`eval`, `readback`, and their composition `step`) let us consolidate
T3 and C4 into a single axiom, and derive them as theorems.
## The preservation story (sketch)
For the full discharge:
HasVal v A -- v is a value of type A
HasNeu n A -- n is a neutral at type A
defined mutually-inductively (logical-relations style) over CVal /
CNeu. The three obligations are:
1. **eval preserves typing.** Given a well-typed term `t : A` under
a well-typed env, `eval env t : A` — i.e. `HasVal (eval env t) A`.
2. **readback preserves typing.** Given `HasVal v A`,
`readback v` is a well-typed term of type `A` in the open context.
3. **step preserves typing.** Composition of (1) + (2) at the empty
env gives: `HasType Γ t A → HasType Γ (CTerm.step t) A`, i.e. the
classical subject reduction.
Once (3) holds, T3 (transport subject reduction) and C4 (composition
subject reduction) are immediate corollaries — instantiate at the
`.transp` / `.comp` constructors and use their `HasType` rules.
## MVP in this module
HasVal / HasNeu are *opaque stubs* — their full structural definition
is deferred. The three preservation axioms are stated with
Lean-discharge provenance (future work will prove them by induction
on the inductive definition once HasVal / HasNeu are concretely
populated). The crucial consolidation is the single axiom
`CTerm.step_preserves_type`, from which T3 and C4 follow as theorems
— eliminating the need for separate step-level axioms for each
type-former.
## Why this is consolidation, not just renaming
Before Stage 2.3: T3 and C4 were independently posited step-level
axioms, each specific to a type-former (`.transp` / `.comp`). Adding
another type-former (e.g. Σ transport once Stage 2.4 or beyond) would
require a new axiom.
After Stage 2.3: T3 and C4 are *theorems*, derivable from the single
`step_preserves_type` axiom. New type-formers get subject reduction
for free — as long as they have a typing rule in `HasType`, they
automatically inherit preservation under `CTerm.step`. The axiom
surface scales O(1) in type-formers, not O(n).
-/
import CubicalTransport.Typing
import CubicalTransport.Readback
-- ── Semantic typing (declarative stubs) ─────────────────────────────────────
/-- `HasVal v A` — the value `v` inhabits type `A` semantically.
Full inductive definition is Lean-discharge future work; for now
this is an opaque predicate whose structural properties are
captured by the preservation axioms below. -/
opaque HasVal : CVal → CType → Prop
/-- `HasNeu n A` — the neutral `n` is a stuck term of type `A`.
Mutual partner to `HasVal`. -/
opaque HasNeu : CNeu → CType → Prop
/-- Semantic well-typedness of an environment: every binding's value
has the type the context assigns to the name. Declarative;
populated in lockstep with `HasVal`. -/
opaque EnvHasType : CEnv → Ctx → Prop
-- ── Preservation axioms ─────────────────────────────────────────────────────
/-- **eval preserves typing.** If `t : A` in context `Γ` and `env`
inhabits `Γ` semantically, then `eval env t` is a value of type `A`.
**Lean-discharge obligation.** Proof: mutual structural induction
on the `eval` / `vApp` / `vPApp` / `vTransp` / `vHCompValue` /
`vCompAtTerm` / `vCompNAtTerm` arms, using the HasType typing
rules to produce HasVal / HasNeu witnesses at each arm.
The full discharge requires HasVal / HasNeu to be inductively
populated (currently opaque); this is future Lean work. -/
axiom eval_preserves_type
(env : CEnv) (Γ : Ctx) (t : CTerm) (A : CType)
(hEnv : EnvHasType env Γ)
(ht : HasType Γ t A) :
HasVal (eval env t) A
/-- **readback preserves typing.** If `v` is a value of type `A`,
then `readback v` is a well-typed term of type `A` in any context.
**Lean-discharge obligation.** Mutual structural recursion on the
`readback` / `readbackNeu` arms, each producing a `HasType` derivation
from the corresponding `HasVal` / `HasNeu` witness. -/
axiom readback_preserves_type
(Γ : Ctx) (v : CVal) (A : CType)
(hv : HasVal v A) :
HasType Γ (readback v) A
/-- The empty context / empty env is trivially well-typed — foundational
base case for threading the preservation story through `CTerm.step`. -/
axiom EnvHasType.nil : EnvHasType .nil []
/-- **CTerm.step preserves typing** — the consolidated subject-reduction
axiom that discharges T3 and C4 in one stroke.
**Lean-discharge obligation.** Composition of `eval_preserves_type`
(at `.nil` / `[]`, via `EnvHasType.nil`), `readback_preserves_type`,
and the definition `CTerm.readback t = readback (eval .nil t)`.
The opaque `CTerm.step` is tied to `CTerm.readback` via the Week 7
step↔eval bridge — the bridge is what makes this axiom's discharge
concrete once HasVal is populated.
**Scope note.** Stated over arbitrary `Γ`: the intuition is that
step preserves the context-typing since the reduction lives inside
the term (not the context). The discharge via empty-env readback
uses a weakening / threading argument that is valid because
`CTerm.step` does not introduce free variables. -/
axiom CTerm.step_preserves_type
(Γ : Ctx) (t : CTerm) (A : CType) (ht : HasType Γ t A) :
HasType Γ (CTerm.step t) A