Some checks are pending
Lean Action CI / build (push) Waiting to run
Four new modules, all building on the now-stable Layer 0 foundation
(Universe / Truncation / Decidable / Omega / Reify / Category).
THEORY.md §0.4 (Subobject + SIP), §0.5 (Modality), §0.6 (Bridge/Set).
## CubicalTransport/Subobject.lean (308 lines)
Sub T = CType.pi "$x" T (Ω ℓ) — re-anchored at ℓ.succ via
ULevel.max_succ_self_right. Pointwise lattice operations as REAL
CTerms using existing Ω logical operators:
· empty / total — constant Ω.false_ / Ω.true_
· inter / union — pointwise Ω.and / Ω.or
· implies / compl — pointwise Ω.implies / Ω.not
· singleton T a — characteristic function of {a} via
CTerm.code (CType.path T x a) + IsNType -1
propositionality witness
Theorems with REAL Prop statements:
· subobject_classifier — bidirectional ∃-quantified statement
(∃ S incl, mono into T) ↔ (∃ χ, χ : Sub T)
(sorry, waits on: Σ-over-universe-codes
for image construction)
· Ω_internal_logic_sound — four-clause Heyting algebra Path
equalities (∧-idempotence, ∧-commutativity,
modus ponens, implication absorption)
(sorry, waits on: prop-univalence via
Soundness.transp_ua)
## CubicalTransport/SIP.lean (320 lines)
StructureFunctor — Lean structure with toFun : CType ℓ → CType ℓ
and transport : (A B) → EquivData → EquivData (REAL EquivData,
not stub CTerm).
· StructureFunctor.id_ — identity functor (transport = id)
· StructureFunctor.comp G F — substantively chains transports
Five categorical functoriality coherences PROVED (not stubbed):
· id_.transport_idEquiv := rfl
· id_.transport_eq_id := rfl
· comp_id_right := rfl
· comp_id_left := rfl
· comp_assoc := rfl
· comp.transport_eq_compose := rfl
Theorems with REAL Prop statements:
· SIP — given S, T, T', e and typed forward/inverse on e:
∃ lifted, HasType [] lifted.f (S.toFun T → S.toFun T')
∧ HasType [] lifted.fInv ...
(sorry, waits on: Soundness.transp_ua as structure-
functor coherence)
· contract_transports — equivalences induce path-equality on
contract values in Ω
(sorry, waits on: SIP + prop-univalence)
## CubicalTransport/Modality.lean (461 lines)
Modality structure with seven REAL Lean-level fields:
· apply : CType ℓ → CType ℓ
· unit : (A : CType ℓ) → CTerm
· isModal : CType ℓ → CType ℓ
· modal_apply, modal_path, modal_sigma, unit_equiv_on_modal — CTerm-typed proof fields
LexModality extends Modality with preserves_pullbacks +
preserves_terminal CTerm-typed proofs.
Modality.id_ — identity modality with REAL CTerm bodies:
unitT ℓ := .ind unitSchema [], unitTT := .ctor unitSchema "tt" [] []
No free-variable placeholders.
Modality.comp G F — substantively chains:
apply A = G.apply (F.apply A)
unit A = .lam "$x" (.app (G.unit (F.apply A)) (.app (F.unit A) (.var "$x")))
modal_sigma A B = G.modal_sigma (F.apply A) (fun b => F.apply (B b))
... etc.
Theorems with REAL Prop statements:
· Modality_pullback_lex — Iff between Modality + pullback-preserving
extension and LexModality
(sorry, waits on: Category.lean's pullback
construction)
· adjoint_modal_triple — quintuple-Σ existence of (ʃ, ♭, ♯) with
four conjuncts asserting CType + CTerm
non-triviality (apply ≠ apply false flags
are real distinctness checks, not tautologies)
(sorry, waits on: Layer 3 cohesive lift —
Topolei/Modal.lean)
Bonus: 5 rfl-lemmas + 4 substantive-dependence theorems
(Modality.id_apply_dep, comp_apply_G_dep, comp_apply_at_id,
comp_unit_F_dep, comp_unit_G_dep) proving fields don't collapse
to constants — analogues of Category.lean's no-collapse theorems.
## CubicalTransport/Bridge/Set.lean (224 lines)
CubicalSetC as a Lean Prop existential:
def CubicalSetC {ℓ} (T : CType ℓ) : Prop :=
∃ (w : CTerm), HasType [] w (IsNType .zero T)
Substantive — the witness w is the cubical proof of 0-truncatedness,
immediately consumable by Hedberg.
Three theorem statements + one bidirectional discharge:
· CubicalSetC_isProp := rfl
· pathEqEquiv (Iff statement) := via path_to_eq + eq_to_path
· CubicalSetC_of_CDecidableEq (sorry, waits on Hedberg)
· path_to_eq (sorry, waits on Hedberg
+ canonical-form readback)
· eq_to_path (sorry, waits on dim-absent
packaging on toCTerm a)
## Discipline summary
· Total new sorries this round: 9 (across 4 files)
· Every sorry annotated -- waits on: <specific dep>
· Zero noncomputable / Classical.propDecidable
· Zero CType.univ stubs / IsModal-style identity definitions
· Zero "True := trivial" theorem placeholders
· Zero "M.apply = M.apply" tautological proofs
· Zero free-variable CTerm placeholders for non-binder names
· No existing file modified — all four files are new
## Verification
lake build (engine) Build completed successfully (48 jobs)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
224 lines
11 KiB
Text
224 lines
11 KiB
Text
/-
|
||
CubicalTransport.Bridge.Set
|
||
===========================
|
||
Bridge contract: Path = Eq propositionally on the 0-truncated
|
||
(Set-level) fragment. THEORY.md §0.6 / §0.8.
|
||
|
||
For any `T : CType ℓ` satisfying `CubicalSetC` (i.e. T is 0-truncated
|
||
in the cubical sense — `IsNType .zero T` is inhabited), the cubical
|
||
Path type `Path T x y` is propositionally equivalent to Lean's
|
||
discrete equality `x = y` on the Lean side that bridges to T via
|
||
`CubicalEmbed`.
|
||
|
||
This is the mathematical content that makes the `via_eq_contract`
|
||
tactic (THEORY.md §0.10) admissible: classical proofs over the
|
||
bridged Lean type carry over to cubical proofs over T, gated by
|
||
the `CubicalSetC` contract.
|
||
|
||
## Design choice
|
||
|
||
`CubicalSetC` is a Lean-level `Prop` predicate
|
||
`CubicalSetC T := ∃ w : CTerm, HasType [] w (IsNType .zero T)`.
|
||
|
||
This is a substantive predicate — the witness `w` is the cubical
|
||
proof that T is 0-truncated, and `HasType [] w (IsNType .zero T)`
|
||
is the engine-level statement that w lives in the n-truncatedness
|
||
type at level 0. Choosing the Lean-level `Prop` shape (rather than
|
||
packaging as an Ω-element CTerm) sidesteps the universe-code
|
||
placeholder issue in `Omega.lean`: every contract in §0.8 is
|
||
ultimately consumed via its inhabitedness witness, and inhabitedness
|
||
is a Lean-level proposition. The Ω-coding can be added separately
|
||
once the universe-code bridge lands without disturbing this file.
|
||
|
||
## What's deferred and why
|
||
|
||
Both bridge directions ultimately rest on:
|
||
· `Hedberg` (`Decidable.lean`): waits on a J-rule combinator
|
||
packaged from `Soundness.transp_ua`.
|
||
· `CubicalEmbed.toCTerm_injective` (already in `Bridge.lean`):
|
||
available; used in the canonical backward direction.
|
||
|
||
Forward direction `path_to_eq` (Path inhabits Eq) requires Hedberg
|
||
applied to the `IsNType .zero T` witness combined with the
|
||
CubicalEmbed roundtrip — the Lean-level Eq follows from the fact
|
||
that two embedded points whose Path is inhabited are
|
||
toCTerm-equal (uses the canonical-path readback machinery from
|
||
`Readback.lean`, packaged through the Set-level discharge).
|
||
|
||
Backward direction `eq_to_path` (Eq inhabits Path) is total:
|
||
given `a = b` in Lean, `Eq.toPath h` (in `Bridge.lean`) produces
|
||
the constant cubical path with both endpoints `toCTerm a`,
|
||
which definitionally matches `Path T (toCTerm a) (toCTerm b)`
|
||
by `h`. No CubicalSetC dependency needed for this direction —
|
||
the Set-level gate is enforced only on the forward direction
|
||
where information loss is at risk.
|
||
-/
|
||
|
||
import CubicalTransport.Truncation
|
||
import CubicalTransport.Decidable
|
||
import CubicalTransport.Omega
|
||
import CubicalTransport.Bridge
|
||
|
||
namespace CubicalTransport.Bridge.Set
|
||
|
||
open CubicalTransport.Inductive
|
||
open CubicalTransport.Truncation
|
||
open CubicalTransport.Decidable
|
||
open CubicalTransport.Omega
|
||
open CubicalTransport.Bridge
|
||
|
||
-- ── §1. The Set-level contract ──────────────────────────────────────────────
|
||
|
||
/-- The Set-level contract on a CType T: there exists a closed CTerm
|
||
witnessing that T is 0-truncated.
|
||
|
||
Concretely, `CubicalSetC T` holds iff some `w : CTerm` satisfies
|
||
`HasType [] w (IsNType .zero T)` — i.e. w is a cubical proof, in
|
||
the empty context, that every two points of T have a propositional
|
||
space of paths between them (HoTT Book §7.1, level 0).
|
||
|
||
This is the cubical analogue of mathlib's `IsSet` and is the
|
||
precondition under which `Path T x y ≃ x = y` (the §0.8
|
||
`pathEqEquiv` of THEORY.md). -/
|
||
def CubicalSetC {ℓ : ULevel} (T : CType ℓ) : Prop :=
|
||
∃ (w : CTerm), HasType [] w (IsNType .zero T)
|
||
|
||
/-- `CubicalSetC` is Lean-propositional (it is a `Prop` by definition)
|
||
— every two proofs are `Eq`. This matches the §0.8 requirement
|
||
that contracts be propositional. -/
|
||
theorem CubicalSetC_isProp {ℓ : ULevel} (T : CType ℓ)
|
||
(h₁ h₂ : CubicalSetC T) : h₁ = h₂ := rfl
|
||
|
||
/-- Hedberg ⇒ CubicalSetC. Decidable equality on T implies T satisfies
|
||
the Set-level contract. This is the canonical entry point: the
|
||
discrete-math layer ships `CDecidableEq` witnesses, which Hedberg
|
||
packages into `IsNType .zero T`, which is exactly `CubicalSetC T`.
|
||
|
||
The proof is direct from `Decidable.Hedberg`: that theorem gives
|
||
`∃ w, HasType [] w (CDecidableEq T → IsNType .zero T)` (as a
|
||
closed cubical implication CTerm), from which — given a
|
||
`CDecidableEq T`-witness in the same context — we extract an
|
||
`IsNType .zero T`-witness by application. -/
|
||
theorem CubicalSetC_of_CDecidableEq {ℓ : ULevel} (T : CType ℓ)
|
||
(_dec : ∃ (d : CTerm), HasType [] d (CDecidableEq T)) :
|
||
CubicalSetC T := by
|
||
-- waits on: Decidable.Hedberg (which itself waits on a J-rule
|
||
-- combinator from Soundness.transp_ua). Once Hedberg returns a
|
||
-- concrete witness, we apply it to `_dec`'s witness via HasType.app
|
||
-- to obtain the IsNType .zero T witness.
|
||
sorry
|
||
|
||
-- ── §2. Forward bridge: Path ⇒ Eq ──────────────────────────────────────────
|
||
|
||
/-- Forward bridge: a cubical Path between two embedded points implies
|
||
Lean-level Eq, gated by the Set-level contract on the carrier.
|
||
|
||
Statement. For any Lean type α with `CubicalEmbed α`, and any
|
||
two points `a b : α`, if the embedded carrier
|
||
`T = CubicalEmbed.ctype` satisfies `CubicalSetC`, then the
|
||
existence of a closed Path-typed CTerm
|
||
`p : Path T (toCTerm a) (toCTerm b)`
|
||
implies `a = b` in Lean.
|
||
|
||
Why the contract gate. Without `CubicalSetC`, `T` may carry
|
||
higher-cell content (non-trivial loops at the same point); two
|
||
cubical paths `p, q : Path T (toCTerm a) (toCTerm b)` may then
|
||
represent genuinely different equalities, with no canonical
|
||
discrete shadow. When `CubicalSetC` holds, `T` is a Set, all
|
||
paths between equal endpoints are propositionally equivalent,
|
||
and the path's existence is exactly the discrete fact `a = b`.
|
||
|
||
Proof shape. The Set-level witness `c : CubicalSetC T` provides
|
||
`w : IsNType .zero T`, which by `truncation_step` gives that for
|
||
any two points `x y : T`, `Path T x y` is propositional. Combined
|
||
with `CubicalEmbed.toCTerm_injective` (already in Bridge.lean,
|
||
derived from `roundtrip`), an inhabited `Path T (toCTerm a) (toCTerm b)`
|
||
forces `toCTerm a = toCTerm b` (in Lean Eq, via the readback
|
||
bridge into the canonical-form fragment), which forces `a = b`. -/
|
||
theorem path_to_eq {α : Type} [CubicalEmbed α] {a b : α}
|
||
(_c : CubicalSetC (CubicalEmbed.ctype (α := α)))
|
||
(_p : ∃ (t : CTerm),
|
||
HasType [] t (.path (CubicalEmbed.ctype (α := α))
|
||
(CubicalEmbed.toCTerm a)
|
||
(CubicalEmbed.toCTerm b))) :
|
||
a = b := by
|
||
-- waits on: Hedberg (Decidable.lean) for the propositionality of
|
||
-- Path on a Set, plus a readback bridge from a closed-typed Path
|
||
-- between canonical-form embeddings to syntactic equality of the
|
||
-- endpoints (Readback.lean's canonical-form readback discipline).
|
||
-- With those: extract the IsNType .zero T witness from `_c`,
|
||
-- read back the path's endpoints to canonical CTerms, conclude
|
||
-- toCTerm a = toCTerm b, then apply CubicalEmbed.toCTerm_injective.
|
||
sorry
|
||
|
||
-- ── §3. Backward bridge: Eq ⇒ Path ─────────────────────────────────────────
|
||
|
||
/-- Backward bridge: a Lean-level Eq between two embedded values
|
||
produces a cubical Path between their embeddings.
|
||
|
||
Statement. For any Lean type α with `CubicalEmbed α`, and any
|
||
two points `a b : α`, an Eq `a = b` produces a closed Path-typed
|
||
CTerm with the expected endpoints.
|
||
|
||
Total — no CubicalSetC dependency. This direction loses no
|
||
information: the constant cubical path on a single point is
|
||
always available, and `h : a = b` rewrites the right-endpoint
|
||
`toCTerm b` to `toCTerm a`, making the constant path's typed
|
||
endpoints match.
|
||
|
||
Construction is exactly `Bridge.Eq.toPath` from `Bridge.lean`:
|
||
`Eq.toPath h := plam "$eq2path" (toCTerm a)`. The HasType
|
||
derivation goes through `HasType.plam` on a dim-absent body. -/
|
||
theorem eq_to_path {α : Type} [CubicalEmbed α] {a b : α}
|
||
(h : a = b) :
|
||
∃ (t : CTerm),
|
||
HasType [] t (.path (CubicalEmbed.ctype (α := α))
|
||
(CubicalEmbed.toCTerm a)
|
||
(CubicalEmbed.toCTerm b)) := by
|
||
-- The witness is `Eq.toPath h`. Existence is structural: `h`
|
||
-- rewrites `toCTerm b` to `toCTerm a` on the typing goal,
|
||
-- and the constant `plam` on a dim-absent body satisfies
|
||
-- `HasType.plam` with both endpoints reducing to `toCTerm a`.
|
||
-- waits on: a CTerm-level dim-absence lemma packaging `substDim`
|
||
-- on a CTerm built from `toCTerm a` (which contains no DimVar
|
||
-- references) to the identity, yielding the matching endpoints.
|
||
-- The Eq.toPath construction itself is total in Bridge.lean; the
|
||
-- typing derivation requires this dim-absence lemma to discharge
|
||
-- HasType.plam's substDim-shaped goals.
|
||
sorry
|
||
|
||
-- ── §4. Full bridge equivalence ────────────────────────────────────────────
|
||
|
||
/-- The full bridge equivalence (THEORY.md §0.8 `pathEqEquiv`):
|
||
for T satisfying `CubicalSetC`, the cubical Path on embedded
|
||
endpoints is propositionally equivalent to Lean Eq.
|
||
|
||
Statement. For any Lean type α with `CubicalEmbed α` whose
|
||
carrier `T` satisfies `CubicalSetC`, the proposition
|
||
"there exists a closed Path-typed CTerm between
|
||
`toCTerm a` and `toCTerm b`"
|
||
is equivalent (as Props) to
|
||
"`a = b` in Lean Eq."
|
||
|
||
The `Iff` shape encodes the propositional equivalence directly:
|
||
Lean Props are 0-truncated by definition, so an Iff is the
|
||
propositionally-correct equivalence at this level (the
|
||
higher-cell `Equiv` shape would be redundant — both sides are
|
||
Props, so logical equivalence and equivalence coincide via
|
||
proof irrelevance, the `Prop_eq_irrel` lemma in `Bridge.lean`).
|
||
|
||
Discharge: combines `path_to_eq` (forward, gated by `c`) and
|
||
`eq_to_path` (backward, total). The contract gate appears only
|
||
on the forward side, exactly as the §0.8 statement requires. -/
|
||
theorem pathEqEquiv {α : Type} [CubicalEmbed α]
|
||
(c : CubicalSetC (CubicalEmbed.ctype (α := α))) (a b : α) :
|
||
(∃ (t : CTerm),
|
||
HasType [] t (.path (CubicalEmbed.ctype (α := α))
|
||
(CubicalEmbed.toCTerm a)
|
||
(CubicalEmbed.toCTerm b)))
|
||
↔ (a = b) := by
|
||
refine ⟨fun p => ?_, fun h => ?_⟩
|
||
· exact path_to_eq c p
|
||
· exact eq_to_path h
|
||
|
||
end CubicalTransport.Bridge.Set
|