Imports
/- Copyright (c) 2026 Terence Rokop. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Terence Rokop -/ module public import Geb.Mathlib.Data.PFunctor.Presheaf.Basic

Prototype: the finite-type universe over a non-discrete base

Throwaway exploration, not upstream-eligible content. Every declaration here is Classical.choice-free.

The universe of [GhaniNordvallForsbergMalatesta2015], Examples 2.5 and 2.6, with the decoding taking values in a category of finite sets — a genuine category, not a discrete one. Geb/Mathlib/Data/PFunctor/IndRec/Universes.lean writes the same universe over Type treated as discrete, which is what the inductive-recursive presentation requires; this module asks what a presheaf polynomial functor over a base with its morphisms restored computes instead. The answer is in the sibling Value module.

The shape presheaf and the arities are coproducts of representables, which is the presentation a family of objects acquires under the embedding of the free coproduct completion Fam(C) into PSh(C) (Fam(C) is the free set-indexed coproduct completion, Remarks 2.3 of [GhaniNordvallForsbergMalatesta2015]). The type former is a parameter, so the dependent-sum and dependent-product universes are two instances of one functor differing only in the shape-output map q.

Main definitions

    Card / El — the base category's objects (the finite cardinals, with functions as morphisms) and their elements.

    Code / Former / out — the code formers, a type former, and the object a code former's output decodes to.

    Idx / bound — the representable summands of a code former's arity and the object each is indexed by: bind's are the code being bound and the family under the binder.

    Shp / Dir — the shapes and directions: the total spaces of the shape presheaf Σ_c y(out c) and of the arity presheaf Σ_k y(bound c k).

    universeData / universeFunctor — the operations and the functor with its seven functor laws, both parameterized by the type former.

    sigmaFormer / piFormer / sigmaUniverse / piUniverse — the dependent-sum and dependent-product formers and the two functors they give.

Main statements

    directionRestr_id_law through reindex_comp_law — the seven functor laws.

Implementation notes

The base is defined here rather than taken to be Geb/Mathlib/CategoryTheory/FinSetSkel, which has the same objects. That category seals FinSetSkel.Hom irreducible so that morphism equality is decidable without Classical.choice; the seal blocks the definitional reasoning this construction runs on. The p.r.a. laws ReindexId and ReindexComp compare directions over shapes whose morphism components are different composites, and the arity reindexing here is the identity map because the arity depends on the shape only through its code former. Both rely on composition being definitionally associative and unital, which holds for functions and not past the seal: unfolding a sealed composite reaches a projection out of the irreducible Hom and the elaborator fails rather than getting stuck. FinSetSkel.toIdxFun and FinSetSkel.ofIdxFun exhibit the two bases' correspondence.

Shp and Dir are the total spaces of presheaves of the form Σ_k y(bound k), so every restriction map — directionRestr, shapeRestr — is precomposition. The shape restriction is written by projection and eqToHom rather than by matching on the shape, which keeps (shapeRestr g a).1.1 definitionally equal to a.1.1; since Dir mentions only that component, the arity reindexing is the identity.

References

    [GhaniNordvallForsbergMalatesta2015]

    [HancockMcBrideGhaniMalatestaAltenkirch2013]

    [Weber2007]

Tags

prototype, inductive-recursive, presheaf, universe, parametric right adjoint, finite set

@[expose] public sectionopen CategoryTheorynamespace GebProto.FinCardUniverse

The base category

An object of the base: a finite cardinal.

The number of elements.

@[ext] structure Card : Type where len : deriving DecidableEq

The elements of an object.

abbrev El (S : Card) : Type := Fin S.len

The base category: finite cardinals and functions between their elements. Composition is function composition, so the category laws hold definitionally.

instance cardCategory : SmallCategory Card where Hom X Y := El X El Y id _ := _root_.id comp f g := g f id_comp _ := rfl comp_id _ := rfl assoc _ _ _ := rfl

Codes

The code formers: one nullary former per object of the base, and one binder former taking an object and a family of objects indexed by its elements.

The code of the object c.

The binder former at the object S and the family T.

inductive Code where | iota (c : Card) | bind (S : Card) (T : El S Card)

A type former: what the binder does to an object and a family of objects indexed by its elements.

abbrev Former : Type := (S : Card) (El S Card) Card

The object a code former's output decodes to.

def out (former : Former) : Code Card | .iota c => c | .bind S T => former S T

The representable summands of a code former's arity: iota has none, bind has the code it binds and one code per element of the bound object.

def Idx : Code Type | .iota _ => Empty | .bind S _ => Unit El S

The object a summand is indexed by.

def bound : (c : Code) Idx c Card | .iota _, k => k.elim | .bind S _, .inl _ => S | .bind _ T, .inr s => T s

Shapes and directions

The shapes: the total space of the shape presheaf Σ_c y(out c). A shape is a code former together with a morphism into the object its output decodes to.

def Shp (former : Former) : Type := Σ c : Code, Σ j : Card, (j out former c)

The directions of a shape: the total space of the arity presheaf Σ_k y(bound c k). Only the shape's code former is used, so shapes sharing a code former have the same directions.

def Dir {former : Former} (a : Shp former) : Type := Σ k : Idx a.1, Σ i : Card, (i bound a.1 k)

The functor

The operations of the universe endofunctor at a type former. Every restriction map is precomposition.

def universeData (former : Former) : PresheafPFunctorData Card Card where A := Shp former B := Dir r := fun x x.2.2.1 q := fun a a.2.1 directionRestr := fun _a _i i' g d d.1.1, i', g eqToHom d.2.symm d.1.2.2, rfl shapeRestr := fun _j j' g a a.1.1, j', g eqToHom a.2.symm a.1.2.2, rfl reindex := fun _j _j' _g _a _i d d

The functor laws

Every restriction map is precomposition, so the laws are the category laws, which hold definitionally for functions. They are stated separately rather than inline because reindex_comp_law needs shapeRestr_comp_law by name: the law is stated relative to it.

directionRestr preserves identities.

theorem directionRestr_id_law (former : Former) : (universeData former).DirectionRestrId := former:Former(universeData former).DirectionRestrId former:Formera:(universeData former).Ai:Card(universeData former).directionRestr a (𝟙 i) = id former:Formera:(universeData former).Ai:Cardd:(universeData former).Direction a i(universeData former).directionRestr a (𝟙 i) d = id d former:Formera:(universeData former).Ak:Idx a.fstv:Cardφ:v bound a.fst k(universeData former).directionRestr a (𝟙 ((universeData former).rCurried a k, v, φ)) k, v, φ, = id k, v, φ, All goals completed! 🐙

directionRestr reverses composition.

theorem directionRestr_comp_law (former : Former) : (universeData former).DirectionRestrComp := former:Former(universeData former).DirectionRestrComp former:Formera:(universeData former).A_i:Cardi':Cardi'':Cardf:i' _ig:i'' i'(universeData former).directionRestr a (g f) = (universeData former).directionRestr a g (universeData former).directionRestr a f former:Formera:(universeData former).A_i:Cardi':Cardi'':Cardf:i' _ig:i'' i'd:(universeData former).Direction a _i(universeData former).directionRestr a (g f) d = ((universeData former).directionRestr a g (universeData former).directionRestr a f) d former:Formera:(universeData former).Ai':Cardi'':Cardg:i'' i'k:Idx a.fstv:Cardφ:v bound a.fst kf:i' (universeData former).rCurried a k, v, φ(universeData former).directionRestr a (g f) k, v, φ, = ((universeData former).directionRestr a g (universeData former).directionRestr a f) k, v, φ, All goals completed! 🐙

shapeRestr preserves identities.

theorem shapeRestr_id_law (former : Former) : (universeData former).ShapeRestrId := former:Former(universeData former).ShapeRestrId former:Formerj:Card(universeData former).shapeRestr (𝟙 j) = id former:Formerj:Carda:{ toSliceDomPFunctor := (universeData former).toSliceDomPFunctor, q := (universeData former).q }.Shape j(universeData former).shapeRestr (𝟙 j) a = id a former:Formerc:Codev:Cardψ:v out former c(universeData former).shapeRestr (𝟙 ({ toSliceDomPFunctor := (universeData former).toSliceDomPFunctor, q := (universeData former).q }.q c, v, ψ)) c, v, ψ, = id c, v, ψ, All goals completed! 🐙

shapeRestr reverses composition.

theorem shapeRestr_comp_law (former : Former) : (universeData former).ShapeRestrComp := former:Former(universeData former).ShapeRestrComp former:Former_j:Cardj':Cardj'':Cardg:j' _jh:j'' j'(universeData former).shapeRestr (h g) = (universeData former).shapeRestr h (universeData former).shapeRestr g former:Former_j:Cardj':Cardj'':Cardg:j' _jh:j'' j'a:{ toSliceDomPFunctor := (universeData former).toSliceDomPFunctor, q := (universeData former).q }.Shape _j(universeData former).shapeRestr (h g) a = ((universeData former).shapeRestr h (universeData former).shapeRestr g) a former:Formerj':Cardj'':Cardh:j'' j'c:Codev:Cardψ:v out former cg:j' { toSliceDomPFunctor := (universeData former).toSliceDomPFunctor, q := (universeData former).q }.q c, v, ψ(universeData former).shapeRestr (h g) c, v, ψ, = ((universeData former).shapeRestr h (universeData former).shapeRestr g) c, v, ψ, All goals completed! 🐙

The arity reindexing is a morphism of arity presheaves. It is the identity map, the arity depending on the shape only through its code former.

theorem reindex_naturality_law (former : Former) : (universeData former).ReindexNaturality := former:Former(universeData former).ReindexNaturality former:Former_j:Card_j':Card_g:_j' _j_a:(universeData former).toSlicePFunctor.Shape _j_i:Card_i':Card_f:_i' _i(universeData former).directionRestr (↑_a) _f (universeData former).reindex _g _a = (universeData former).reindex _g _a (universeData former).directionRestr (↑((universeData former).shapeRestr _g _a)) _f All goals completed! 🐙

The arity reindexing along an identity is the identity.

theorem reindex_id_law (former : Former) : (universeData former).ReindexId (shapeRestr_id_law former) := former:Former(universeData former).ReindexId former:Former_j:Card_a:(universeData former).toSlicePFunctor.Shape _j_i:Card_b:(universeData former).Direction (↑((universeData former).shapeRestr (𝟙 _j) _a)) _i(universeData former).reindex (𝟙 _j) _a _b = cast _b All goals completed! 🐙

The arity reindexing along a composite is the composite of the reindexings.

theorem reindex_comp_law (former : Former) : (universeData former).ReindexComp (shapeRestr_comp_law former) := former:Former(universeData former).ReindexComp former:Former_j:Card_j':Card_j'':Card_g:_j' _j_h:_j'' _j'_a:(universeData former).toSlicePFunctor.Shape _j_i:Card_b:(universeData former).Direction (↑((universeData former).shapeRestr (_h _g) _a)) _i(universeData former).reindex (_h _g) _a _b = (universeData former).reindex _g _a ((universeData former).reindex _h ((universeData former).shapeRestr _g _a) (cast _b)) All goals completed! 🐙

The universe endofunctor at a type former: the operations with the seven functor laws.

The two type formers

The dependent-sum former: the object of pairs.

def sigmaFormer : Former := fun S T (List.ofFn fun s : El S (T s).len).sum

The dependent-product former: the object of sections.

def piFormer : Former := fun S T (List.ofFn fun s : El S (T s).len).prod

The universe closed under dependent sums.

The universe closed under dependent products.

end GebProto.FinCardUniverse