cubical-transport-hott-lean4/CubicalTransport/Decidable.lean
Maximus Gorog f6231f3e64
Some checks are pending
Lean Action CI / build (push) Waiting to run
Layer 0 substrate (Truncation, Decidable, Omega, Category, Reify)
+ CType.El / CTerm.code constructors (universe-coding); ABI v5

## Layer 0 substrate (5 new modules per docs/THEORY.md §0)

CubicalTransport/Truncation.lean (367 lines)
  TruncLevel inductive (-2 = contractible, -1 = prop, 0 = set, …).
  IsNType : substantive Σ/Π/Path tower encoding contractibility,
    propositionality, set-ness, and recursive n-truncatedness.
  Trunc HIT schemas at -2 / -1 / higher levels.
  truncation_step + truncation_hits_props proven by rfl.
  truncation_idempotent (sorry, waits on Modality.lean).
  IsNType_isProp_witness (sorry, waits on funext via J-rule).
  Helpers piSelf/sigmaSelf via ULevel.max_self ▸ rewrite to keep
  IsNType returning at level ℓ cleanly (CCHM Π/Σ at max ℓ ℓ ≠ ℓ
  reductionally without max_self).

CubicalTransport/Decidable.lean (184 lines)
  CDecidable encoded as a real disjoint-union schema (decSchema)
  with two type parameters [A, A→⊥] and constructors inl/inr.
  emptySchema (zero ctors) provides CType.botC at any level.
  CDecidableEq T := Π a b, CDecidable (Path T a b).
  Hedberg theorem statement (sorry, waits on J-rule combinator).

CubicalTransport/Omega.lean (rewritten to use real El-decoder)
  Ω (ℓ) := Σ (P : .univ ℓ), .lift (IsNType .negOne (.El P))
  Eight logical operators (true/false/and/or/implies/not/forall_/
  exists_) as REAL CTerms — no free-variable placeholders, every
  .var "$x" reference is to a binder in the same expression.
  OmegaIsProp (sorry, waits on Soundness.transp_ua for prop-univalence).

CubicalTransport/Reify.lean (115 lines)
  CType-as-CTerm injection helper.  universeSchema with codeOf P
  carrying embedded CType through schema parameter list.  Now
  largely redundant after CTerm.code lands (kept for callers that
  want the singleton-per-CType form rather than the universe-typed
  form).

CubicalTransport/Category.lean (614 lines)
  CCategory ℓ structure: Obj : CType ℓ, Hom : CTerm → CTerm → CType ℓ,
  id, comp, three Path-encoded laws (id_left, id_right, assoc).
  CFunctor / CNatTrans / CAdjoint / CLimit / CColimit with
  substantive structures + naturality + universal property fields.
  CFunctor.id, CFunctor.comp, CNatTrans.id, CNatTrans.vcomp helpers
  with concrete law-discharge bodies.
  CType_as_Category (ℓ) — concrete instance of CType ℓ as a
  CCategory at level ℓ.succ.  Five no-collapse theorems proving
  Hom/id/comp strictly depend on each argument via constructor
  injectivity.
  CCategory_internal (sorry, waits on Subobject + Modality + pullback).

## CType.El / CTerm.code constructors + full cascade

Engine (Lean):
  CType.El {ℓ} (P : CTerm) : CType ℓ — decoder
  CTerm.code {ℓ} (A : CType ℓ) : CTerm — encoder
  CType.El_code_eq : El (code A) = A — propositional (axiom; β-rule
    for the universe code/decode pair, standard CCHM treatment)
  SkeletalCType.El + CType.skeleton .El arm + skeleton_El simp lemma.
  Cascade through Subst, DimLine, DecEq, Value, Eval, Readback,
  Typing, Question, FFITest.  CTerm.code → CVal.vcode evaluation;
  CVal.vcode → CTerm.code readback; HasType.code typing rule.
  IsElLine classifiers for CompQ and TranspQ with computable
  Decidable instances.

Engine (Rust ABI v5):
  CUBICAL_TRANSPORT_ABI_VERSION 4 → 5
  TY_EL = 8, TERM_CODE = 16, VAL_VCODE = 11
  Allocators mk_ty_el / mk_term_code / mk_val_vcode in value.rs / subst.rs
  Marshalling cascade in eval.rs / readback.rs / dim_absent.rs / subst.rs
  Cargo.toml 0.2.0 → 0.3.0
  cubical_transport.h v5 changelog + layout tables for new constructors

## Discipline

  · 5 sorries total, every one annotated -- waits on: <specific dep>
  · Zero noncomputable / Classical.propDecidable
  · Zero CType.univ stubs / IsModal-style identity definitions
  · Zero free-variable placeholders ($Foo_witness)
  · Zero parallel CTypeU type
  · No shortcuts taken — the agent reported the El/code β-rule must
    be axiomatic (since El and code are independent constructors of
    mutually-defined inductives, Lean's kernel cannot reduce them
    without explicit reduction rules); this matches CCHM's standard
    treatment.

## Verification

  lake build (engine)           Build completed successfully (48 jobs)
  ./cubical-test                49/49 smoke + 46/46 properties
  lake build (topolei)          Build completed successfully (90 jobs)
  ./probe-test                  7/7 GPU probes match Lean
  lake build (infoductor-cubical)  Build completed successfully (32 jobs)
  CUBICAL_TRANSPORT_ABI_VERSION = 5

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 09:11:29 -06:00

184 lines
8.1 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
CubicalTransport.Decidable
==========================
Decidable equality at the cubical CType level (THEORY.md
Layer 0 §0.7). Universe-aware (Layer 0 §0.1 cascade).
This module provides:
· `emptySchema` / `CType.botC` — the empty type at any level, the
cubical-side `⊥`. Implemented as the inductive schema with zero
constructors (no point or path ctors); inhabitants are
inaccessible by structural pattern matching.
· `CType.notC A` — `A → ⊥`, the "negation" type at level for
`A : CType `. Coerced to `CType ` via `CType.piSelf` (same-
level pi from `Truncation.lean`'s §1A re-anchoring discipline).
· `decSchema` — the schema for `CDecidable`. Two type parameters
`[A, A → ⊥]`; two point constructors `inl : .param 0 → Dec` and
`inr : .param 1 → Dec`. The schema is two-parameter rather than
one-parameter because `CTypeArg` (per `Syntax.lean`) does not
permit forming `param i → param j` as a single arg shape — the
arrow has to be assembled at instantiation time as a closed
CType supplied via the schema parameter list.
· `CDecidable A` — `A ⊎ (A → ⊥)` as a real CType, instantiating
`decSchema` with parameters `[A, CType.notC A]` at level .
· `CDecidableEq T` — `Π (a b : T), CDecidable (Path T a b)`, the
cubical predicate "equality of T-elements is decidable."
· `Hedberg` — the theorem `CDecidableEq T → IsNType .zero T`
(THEORY.md §0.7), the bridge contract for the discrete-math
layer. The CType-level statement is fully typed; the proof
awaits a J-rule discharge from the engine's transp/comp
primitives (path-induction not yet packaged as a derived
combinator).
## Universe-stratification notes
`emptySchema` has zero parameters and zero ctors; instantiating
`.ind emptySchema []` at any level produces `⊥` at that level.
`CType.botC ` exposes this directly.
`CDecidable` keeps the level of its argument: `A : CType `
produces `CDecidable A : CType ` because the schema is
instantiated at level , and the schema parameter list packages
both `A` and `CType.notC A` at level .
## Hygienic binder names
`CDecidableEq` uses the binder names `"$a"`, `"$b"` for the inner
pi binders; references via `.var "$a"`, `.var "$b"` are scoped
within the same expression and therefore hygienic per the
project's binder-naming discipline.
-/
import CubicalTransport.Truncation
namespace CubicalTransport.Decidable
open CubicalTransport.Inductive
open CubicalTransport.Truncation
-- ── §1. The empty type as a schema ────────────────────────────────────────
/-- The empty type as a CTypeSchema. Zero constructors — no point or
path ctors. Instantiation `.ind emptySchema []` is the cubical
`⊥` at any user-supplied level.
Inhabitants of the empty type are structurally inaccessible: any
eliminator over `.ind emptySchema []` proves the goal vacuously
by exhausting the (empty) constructor list. -/
def emptySchema : CTypeSchema :=
mkSchema "⊥" 0 []
/-- `⊥` as a CType at any level. Polymorphic in the level parameter:
instantiating at `.zero` gives the bottom-universe empty type;
at higher levels gives the same data lifted into the higher
universe (the schema is level-uniform). -/
def CType.botC ( : ULevel) : CType := .ind emptySchema []
/-- Negation as a CType: `¬A := A → ⊥`, with both A and ⊥ at the
same level . Uses `CType.piSelf` (Truncation.lean §1A) to
coerce `max ` back to ``. -/
def CType.notC { : ULevel} (A : CType ) : CType :=
CType.piSelf "$_neg" A (CType.botC )
-- ── §2. The decidable schema ──────────────────────────────────────────────
/-- The schema for `CDecidable`. Two parameters and two
constructors:
· `params := [A, A → ⊥]` at positions 0 and 1
· `inl : .param 0 → CDecidable` (positive witness)
· `inr : .param 1 → CDecidable` (negative witness)
Two-parameter rather than one-parameter because `CTypeArg` does
not permit `.param 0 → .param j`-shaped args (no arrow former at
the CTypeArg level). Instead we close the arrow at instantiation
time, packaging it as the second schema parameter.
No path constructors — `CDecidable` is plain (a sum type, not a
HIT). -/
def decSchema : CTypeSchema :=
mkSchema "CDecidable" 2
[ mkCtor "inl" [.param 0]
, mkCtor "inr" [.param 1] ]
-- ── §3. CDecidable, CDecidableEq ──────────────────────────────────────────
/-- Decidability as a CType (THEORY.md §0.7). `CDecidable A` is the
cubical-side `A ⊎ (A → ⊥)`: a real disjoint union with positive
witness `inl a : CDecidable A` and negative witness `inr na :
CDecidable A` (where `na : A → ⊥`).
Encoded as `.ind decSchema [⟨ℓ, A⟩, ⟨ℓ, A → ⊥⟩]` at level . -/
def CDecidable { : ULevel} (A : CType ) : CType :=
.ind ( := ) decSchema [⟨ℓ, A⟩, ⟨ℓ, CType.notC A⟩]
/-- Decidable equality on T (THEORY.md §0.7):
`Π (a b : T), CDecidable (Path T a b)`.
The CType-level statement of "every two T-elements have
decidably-equal paths." This is the precondition of the
Hedberg theorem (below). -/
def CDecidableEq { : ULevel} (T : CType ) : CType :=
CType.piSelf "$a" T
(CType.piSelf "$b" T
(CDecidable (.path T (.var "$a") (.var "$b"))))
-- ── §4. Hedberg: decidable equality implies set-level ────────────────────
/-- The Hedberg theorem (THEORY.md §0.7, HoTT Book Theorem 7.2.5):
decidable equality on T implies T is a Set (i.e., `IsNType .zero T`).
This is the bridge contract's mathematical content: decidable
equality implies 0-truncation, which makes `Path` and `Eq`
propositionally equivalent (the `pathEqEquiv` of THEORY.md §0.8).
## Statement
For every level and every CType T at level , there exists a
CTerm witnessing the implication
CDecidableEq T → IsNType .zero T
in the empty context. This is the cubical analogue of the
Lean-level `DecidableEq → IsSet` of mathlib.
## Proof sketch (Univalent Foundations §7.2.5)
Given `dec : CDecidableEq T`, define
K (a b : T) (p : Path T a b) : Path T a b
by case analysis on `dec a b`:
· `inl q` (positive): return `q` (constant in `p`).
· `inr nq` (negative): impossible — `nq p` produces an
inhabitant of `⊥`, from which we case-eliminate on the empty
type to produce any `Path T a b`.
In both cases, K is constant in `p`. The standard "constant
endo on Path space implies all paths equal" lemma — proved from
Path-induction (the J rule) — gives Set-ness of T.
The proof requires:
· Case analysis on `CDecidable` (inductive elimination —
present, via `indElim`).
· Empty-type elimination (`emptySchema.ctors = []` so `indElim`
on `.ind emptySchema []` has no branches — proves any goal).
· The K-constant-implies-set lemma, which factors through
Path-induction (J).
The J rule for Path types in this engine lives latently in the
`transp_ua` framework of `Soundness.lean`; assembling it as a
derived combinator requires routing transport through the
`uaLine`-shape, which the engine supports (see `transp_ua`)
but has not yet been packaged as a callable J. -/
theorem Hedberg { : ULevel} (T : CType ) :
∃ (w : CTerm), HasType [] w (CType.piSelf "$dec" (CDecidableEq T)
(IsNType .zero T)) := by
-- waits on: J-rule combinator built from Soundness.transp_ua
-- (CCHM path-induction packaged as a derived combinator). Once J
-- is available, the standard Hedberg construction
-- (K-constant + constant-endo-implies-set) discharges in one step.
sorry
end CubicalTransport.Decidable