/-
Copyright (c) 2026 Terence Rokop. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Terence Rokop
-/modulepublicimportGeb.Mathlib.Data.PFunctor.Slice.BasicpublicimportMathlib.CategoryTheory.Functor.CategorypublicimportMathlib.CategoryTheory.OppositespublicimportMathlib.CategoryTheory.Types.Basic
Presheaf polynomial functors (constructive core)
A presheaf-domain polynomial functor extends a SliceDomPFunctor on the
objects of a category I with a contravariant I-action on arities: for
each shape a, the assignment i ↦ Direction a i extends to a presheaf on
I via a restriction map directionRestr a f. A presheaf polynomial functor
adds the shape-output side: a J-action shapeRestr on shapes with an arity
reindexing reindex, assembling the output as a presheaf on J. This file
is the constructive core of the p.r.a. (parametric right adjoint)
construction, both the domain-restricted functor and the full
(Iᵒᵖ ⥤ Type) → (Jᵒᵖ ⥤ Type) action. Every declaration here is
Classical.choice-free; the categorical packaging that pulls in
Classical.choice from mathlib is in the sibling Presheaf.Functor module.
Directions over i are
SliceDomPFunctor.Direction a i = Subtype (DirectionOver a i), the fiber of
the direction-input map rCurried a over i. The directionRestr field
reindexes these fibers contravariantly.
Main definitions
PresheafDomPFunctorData — the operations: a SliceDomPFunctor with a
restriction map directionRestr.
PresheafDomPFunctorData.DirectionRestrId / DirectionRestrComp — named law Props.
PresheafDomPFunctorData.IsFunctorial — the functor laws bundled.
PresheafDomPFunctorData.elemProj — projection from the presheaf's elements
Σ i, Z.obj ⟨i⟩ to the base I.
PresheafDomPFunctorData.value — the Z-value the assignment gives a
direction.
PresheafDomPFunctorData.IsNatural — naturality of the direction
assignment with respect to directionRestr and Z.map.
PresheafDomPFunctorData.obj — the functor's value on a presheaf Z.
PresheafDomPFunctorData.elemMap — the action of a presheaf morphism α on
the categories of elements, el(Z) ⟶ el(Z').
PresheafDomPFunctorData.map — the action on morphisms of input presheaves
(the bare NatTrans).
PresheafDomPFunctor — the bundle: operations with a functoriality proof.
PresheafPFunctorData — the full operations: the dom operations and the
shape-output map, with the J-action shapeRestr on shapes and the arity
reindexing reindex.
PresheafPFunctorData.ShapeRestrId / ShapeRestrComp / ReindexNaturality /
ReindexId / ReindexComp — the named J-side law Props. ReindexId
and ReindexComp are parameterized on the relevant shapeRestr law, whose
content supplies the non-definitional source-type transport.
PresheafPFunctorData.IsFunctorial — the full functor laws bundled.
PresheafPFunctor — the full bundle: operations with a functoriality proof.
PresheafPFunctor.objRestrElt / objRestr — the restriction action of the
output presheaf on a J-morphism, on a slice element over an arbitrary
projection and on F.obj Z.
PresheafPFunctor.objPresheaf — the output presheaf T(Z) : Jᵒᵖ ⥤ Type, a
Functor value with map_id / map_comp discharged from isFunctorial.
PresheafPFunctor.mapPresheaf — the presheaf morphism
objPresheaf Z ⟶ objPresheaf Z' induced by a morphism of input presheaves.
Main statements
PresheafDomPFunctorData.map_id / map_comp — functoriality of the
domain-restricted action in the input presheaf.
PresheafPFunctor.map_objRestr — the domain map is natural with respect
to the output presheaf's restriction maps.
PresheafPFunctor.objRestrElt_id / objRestrElt_comp — the identity and
composition laws of the element-level restriction objRestrElt.
Notation
The declaration docstrings use the parametric-right-adjoint notation of
[Weber2007]:
T1 — the shape presheaf j ↦ Shape j on J, with shapeRestr as its
restriction maps.
E_T(a) — the arity presheaf i ↦ Direction a.1 i of a shape a on I,
with directionRestr as its restriction maps.
el(T1) — the category of elements of T1: objects are pairs (j, a) with
a : Shape j. As T1 is a presheaf, its elements vary contravariantly, so a
morphism (j, a) ⟶ (j', a') is backed by a J-morphism g : j' ⟶ j (the
opposite direction) with shapeRestr g a = a'. The arity assignment a ↦ E_T(a)
is therefore contravariant on el(T1) (a functor on el(T1)ᵒᵖ); reindex g a
is its action, the presheaf morphism E_T(shapeRestr g a) ⟶ E_T(a).
Implementation notes
The morphism universes of I and J are named vI and vJ (via
[Category.{vI} I] / [Category.{vJ} J]), and every parent and presheaf-functor
argument pins its universes, so no declaration's signature carries an auto-bound
u_N variable. PresheafDomPFunctorData uses
extends SliceDomPFunctor.{uA, uB} I with pinned universes (required for a
later diamond via PresheafDomPFunctorData and SlicePFunctor); pinned
references to it elsewhere take the synthesized order
PresheafDomPFunctorData.{uI, uA, uB, vI}.
The linter.checkUnivs false option suppresses the checkUnivs warning on
the inherited PFunctor universes uA/uB: they are
the two Type universes of the PFunctor parent and appear only together in
the result max, so the linter flags them as a pair that could be unified. The
warning is independent of the morphism universe: naming vI does not remove it,
and it fires even on a Category-free PFunctor-extending structure. This is
the same situation mathlib suppresses in PFunctor.
PresheafPFunctorData is the diamond
extends PresheafDomPFunctorData.{uI, uA, uB, vI} I, SlicePFunctor.{uA, uB, uI, uJ} I J,
which shares the single SliceDomPFunctor parent. The reindex laws
ReindexId / ReindexComp are stated in homogeneous-Eq form, parameterized
on a shapeRestr law, rather than as bare Props: comparing reindex along
𝟙 (resp. a composite) with the identity (resp. the composite of reindexes)
requires a source-type transport whose target equality
(shapeRestr (𝟙 j) a = a, resp. shapeRestr (h ≫ g) a = shapeRestr h (shapeRestr g a))
is ShapeRestrId (resp. ShapeRestrComp) content, not definitional. They are
therefore parameterized on that law and apply it via cast; IsFunctorial
supplies the proof from its earlier shapeRestr_id / shapeRestr_comp fields. A
heterogeneous-Eq formulation would avoid the parameter at the cost of
rw-convenience and mathlib idiom.
References
[Weber2007]
[nLabParametricRightAdjoint]
[GambinoHyland2004]
[GambinoKock2013]
Tags
polynomial functor, presheaf, parametric right adjoint, p.r.a.,
PFunctor, restriction map
Operations of a presheaf-domain polynomial functor over I: a
SliceDomPFunctor on I's objects, with the contravariant I-action
directionRestr making each arity a presheaf on I.
The arity-presheaf restriction: for a morphism i' ⟶ i, reindex
directions of shape a over i to directions over i'.
@[`@[expose]` has no effect outside a `module` fileexpose]defDirectionRestrId{I:TypeuI}[Category.{vI}I](F:PresheafDomPFunctorData.{uI,uA,uB,vI}I):Prop:=∀(a:F.A)(i:I),F.directionRestra(𝟙i)=id
directionRestr reverses composition: directionRestr a (g ≫ f) = directionRestr a g ∘ directionRestr a f.
Total-space projection of a presheaf Z on I to objects of I.
@[`@[expose]` has no effect outside a `module` fileexpose]defelemProj{I:TypeuI}[Category.{vI}I](Z:Iᵒᵖ⥤TypeuZ):(Σi:I,Z.obj⟨i⟩)→I:=Sigma.fst
The Z-value a slice element x over elemProj Z gives a direction
b of shape x.1.1 over i: the Z-value (x.1.2 b.1).2, cast along the
compatibility of x and the constraint condition on b to Z.obj ⟨i⟩.
@[`@[expose]` has no effect outside a `module` fileexpose]defvalue{I:TypeuI}[Category.{vI}I](F:PresheafDomPFunctorData.{uI,uA,uB,vI}I){Z:Iᵒᵖ⥤TypeuZ}(x:F.toSliceDomPFunctor.Obj(elemProjZ))⦃i:I⦄(b:F.toSliceDomPFunctor.Directionx.1.1i):Z.obj⟨i⟩:=cast(congrArg(funk:I↦Z.obj⟨k⟩)(((F.compatible_iff(elemProjZ)x.1.1x.1.2).mpx.2b.1).transb.2))(x.1.2b.1).2
The direction-assignment of x is a natural transformation E_T(a) ⟶ Z,
where a := x.1.1: for every f : i' ⟶ i and direction b over i, the
component assigned to directionRestr a f b equals Z.map f.op applied to value x b.
@[`@[expose]` has no effect outside a `module` fileexpose]defIsNatural{I:TypeuI}[Category.{vI}I](F:PresheafDomPFunctorData.{uI,uA,uB,vI}I){Z:Iᵒᵖ⥤TypeuZ}(x:F.toSliceDomPFunctor.Obj(elemProjZ)):Prop:=∀⦃ii':I⦄(f:i'⟶i)(b:F.toSliceDomPFunctor.Directionx.1.1i),F.valuex(F.directionRestrx.1.1fb)=Z.mapf.op(F.valuexb)
The value of the presheaf-domain functor on Z: the IsNatural subtype
of the slice object on the total-space projection elemProj Z.
@[`@[expose]` has no effect outside a `module` fileexpose]defobj{I:TypeuI}[Category.{vI}I](F:PresheafDomPFunctorData.{uI,uA,uB,vI}I)(Z:Iᵒᵖ⥤TypeuZ):Type(maxuIuZuAuB):={x:F.toSliceDomPFunctor.Obj(elemProjZ)//F.IsNaturalx}
The shape of an element of F.obj Z: its underlying PFunctor shape.
@[`@[expose]` has no effect outside a `module` fileexpose,reducible]defobj.shape{I:TypeuI}[Category.{vI}I]{F:PresheafDomPFunctorData.{uI,uA,uB,vI}I}{Z:Iᵒᵖ⥤TypeuZ}(x:F.objZ):F.A:=x.1.1.1
A component of a natural transformation commutes with the reindexing
cast along an equality of base points.
The action of a natural transformation α : Z ⟶ Z' on the categories of
elements, el(Z) ⟶ el(Z'): ⟨i, z⟩ ↦ ⟨i, α.app ⟨i⟩ z⟩. It preserves the
base-point projection elemProj, so it is a slice morphism over elemProj.
@[`@[expose]` has no effect outside a `module` fileexpose]defelemMap{I:TypeuI}[Category.{vI}I]{ZZ':Iᵒᵖ⥤TypeuZ}(α:NatTransZZ'):(Σi:I,Z.obj⟨i⟩)→(Σi:I,Z'.obj⟨i⟩):=funp↦⟨p.1,α.app⟨p.1⟩p.2⟩
The Z'-component the image under α of a slice element assigns to a
direction is α.app of the Z-component the original assigns to it.
A presheaf-domain polynomial functor: operations together with a
proof they are functorial. Its action is a functor (Iᵒᵖ ⥤ Type) ⥤ Type
(packaged in Presheaf.Functor).
Operations of a presheaf polynomial functor (Iᵒᵖ ⥤ Type) → (Jᵒᵖ ⥤ Type):
the dom operations plus the shape-output map q (via SlicePFunctor), the
J-action shapeRestr on shapes, and the arity reindexing reindex.
The shape-presheaf restriction: for g : j' ⟶ j, reindex shapes over
j to shapes over j'.
The arity reindexing along a J-morphism: a presheaf morphism
E_T(shapeRestr g a) ⟶ E_T(a).
The shape-output-map view of the operations: the shared SliceDomPFunctor
together with the shape-output map q. The diamond merges the
SliceDomPFunctor parent, so this view shares its components with
toPresheafDomPFunctorData.
add_decl_docPresheafPFunctorData.toSlicePFunctor
namespacePresheafPFunctorData
shapeRestr preserves identities.
@[`@[expose]` has no effect outside a `module` fileexpose]defShapeRestrId{I:TypeuI}[Category.{vI}I]{J:TypeuJ}[Category.{vJ}J](F:PresheafPFunctorData.{uI,uJ,uA,uB,vI,vJ}IJ):Prop:=∀(j:J),F.shapeRestr(𝟙j)=id
shapeRestr reverses composition: shapeRestr (h ≫ g) = shapeRestr h ∘ shapeRestr g.
@[`@[expose]` has no effect outside a `module` fileexpose]defShapeRestrComp{I:TypeuI}[Category.{vI}I]{J:TypeuJ}[Category.{vJ}J](F:PresheafPFunctorData.{uI,uJ,uA,uB,vI,vJ}IJ):Prop:=∀⦃jj'j'':J⦄(g:j'⟶j)(h:j''⟶j'),F.shapeRestr(h≫g)=F.shapeRestrh∘F.shapeRestrg
Each reindex g a commutes with directionRestr (a presheaf morphism
E_T(shapeRestr g a) ⟶ E_T(a)): for f : i' ⟶ i,
directionRestr a.1 f ∘ reindex g a = reindex g a ∘ directionRestr (shapeRestr g a).1 f.
Ordinary fiber maps only; no shapeRestr transport.
@[`@[expose]` has no effect outside a `module` fileexpose]defReindexNaturality{I:TypeuI}[Category.{vI}I]{J:TypeuJ}[Category.{vJ}J](F:PresheafPFunctorData.{uI,uJ,uA,uB,vI,vJ}IJ):Prop:=∀⦃jj':J⦄(g:j'⟶j)(a:F.Shapej)⦃ii':I⦄(f:i'⟶i),F.directionRestra.1f∘F.reindexga(i:=i)=F.reindexga(i:=i')∘F.directionRestr(F.shapeRestrga).1f
reindex (𝟙 j) a is the identity, modulo the transport of its source
along ShapeRestrId at j (shapeRestr (𝟙 j) a = a). The transport is the
cast of b along congrArg (fun s ↦ Direction s.1 i) (congrFun (hti j) a).
Parameterized on the identity law hti because that source-type equality is
not definitional.
@[`@[expose]` has no effect outside a `module` fileexpose]defReindexId{I:TypeuI}[Category.{vI}I]{J:TypeuJ}[Category.{vJ}J](F:PresheafPFunctorData.{uI,uJ,uA,uB,vI,vJ}IJ)(hti:F.ShapeRestrId):Prop:=∀⦃j:J⦄(a:F.Shapej)⦃i:I⦄(b:F.Direction(F.shapeRestr(𝟙j)a).1i),F.reindex(𝟙j)ab=cast(congrArg(funs:F.Shapej↦F.Directions.1i)(congrFun(htij)a))b
For g : j' ⟶ j, h : j'' ⟶ j',
reindex (h ≫ g) a = reindex g a ∘ reindex h (shapeRestr g a) (g is the
outer factor), modulo the transport of the source along ShapeRestrComp
(shapeRestr (h ≫ g) a = shapeRestr h (shapeRestr g a)). The transport is the cast
of b along congrArg (fun s ↦ Direction s.1 i) (congrFun (htc g h) a).
Parameterized on the composition law htc because that source-type equality is
not definitional.
All functor laws: the dom laws plus the J-side laws making T1 a
presheaf and E_T a functor on el(T1). The shapeRestr laws precede the
reindex laws because reindex_id / reindex_comp are stated relative to
shapeRestr_id / shapeRestr_comp.
Identity law for shapeRestr.
Composition law for shapeRestr.
reindex is a presheaf morphism (commutes with directionRestr).
Identity law for reindex, relative to shapeRestr_id.
Composition law for reindex, relative to shapeRestr_comp.
The slice element underlying the restriction action of objPresheaf on a
J-morphism g, for a projection p : X → I: restrict the shape along
shapeRestr g and reindex the direction-assignment along reindex g.
@[`@[expose]` has no effect outside a `module` fileexpose]defobjRestrElt{I:TypeuI}[Category.{vI}I]{J:TypeuJ}[Category.{vJ}J](F:PresheafPFunctor.{uI,uJ,uA,uB,vI,vJ}IJ){X:TypeuX}{p:X→I}⦃jj':J⦄(g:j'⟶j)(x:F.toSliceDomPFunctor.Objp)(hq:F.qx.1.1=j):F.toSliceDomPFunctor.Objp:=⟨⟨(F.shapeRestrg⟨x.1.1,hq⟩).1,funb'↦x.1.2(F.reindexg⟨x.1.1,hq⟩(i:=F.rCurried_b')⟨b',rfl⟩).1⟩,(F.compatible_iff___).mprfunb'↦((F.compatible_iff___).mpx.2(F.reindexg⟨x.1.1,hq⟩(i:=F.rCurried_b')⟨b',rfl⟩).1).trans(F.reindexg⟨x.1.1,hq⟩(i:=F.rCurried_b')⟨b',rfl⟩).2⟩
The component the restricted element assigns to a direction is the component
the original assigns to the direction's reindex.
The restriction action of objPresheaf on a J-morphism g, at the level
of F.obj Z: objRestrElt packaged with its naturality, supplied by
reindex_naturality.
Two functions into a common type whose domains are equal are heterogeneously
equal when they agree on heterogeneously-equal inputs. A restriction of
Function.hfunext to a non-dependent codomain.
The output presheaf T(Z) : Jᵒᵖ ⥤ Type, built directly as a Functor
value. Its fiber over j is the subtype of the dom value F.obj Z whose
q-output index is j; its restriction maps are the shape-and-direction
reindex action objRestr, whose map_id / map_comp are discharged
from F.isFunctorial.
Naturality of the dom morphism map with respect to objPresheaf's
J-restriction: for α : NatTrans Z Z', the dom map α carries the fiber of
objPresheaf Z over j into that of objPresheaf Z' (it preserves the
q-output index, the shape being fixed by SliceDomPFunctor.map_fst) and
commutes with the shape-and-direction reindex restriction objRestr g. The
commutation is the interchange of the postcomposition with α (the morphism
action) and the precomposition with reindex g (the restriction), needing no
functor law.
The natural transformation objPresheaf Z ⟶ objPresheaf Z' induced by a
morphism α : Z ⟶ Z' of input presheaves: each component is the dom map α on
the underlying element, restricted to the q-indexed fiber (the dom map
preserves the output index, the shape being fixed by
SliceDomPFunctor.map_fst); naturality is map_objRestr. The categorical
wrapper functor.map reuses it.
@[`@[expose]` has no effect outside a `module` fileexpose]defmapPresheaf{I:TypeuI}[Category.{vI}I]{J:TypeuJ}[Category.{vJ}J](F:PresheafPFunctor.{uI,uJ,uA,uB,vI,vJ}IJ){ZZ':Iᵒᵖ⥤TypeuZ}(α:NatTransZZ'):NatTrans(F.objPresheafZ)(F.objPresheafZ')whereappX:=↾funw↦(⟨F.toPresheafDomPFunctorData.mapαw.1,w.2⟩:(F.objPresheafZ').objX)naturality__g:=byI:Type uIinst✝¹:Category.{vI, uI}IJ:Type uJinst✝:Category.{vJ, uJ}JF:PresheafPFunctorIJZ:Iᵒᵖ⥤Type uZZ':Iᵒᵖ⥤Type uZα:NatTransZZ'x✝¹:Jᵒᵖx✝:Jᵒᵖg:x✝¹⟶x✝⊢ ((F.objPresheafZ).mapg≫↾funw↦⟨F.mapα↑w,⋯⟩)=(↾funw↦⟨F.mapα↑w,⋯⟩)≫(F.objPresheafZ').mapgextwI:Type uIinst✝¹:Category.{vI, uI}IJ:Type uJinst✝:Category.{vJ, uJ}JF:PresheafPFunctorIJZ:Iᵒᵖ⥤Type uZZ':Iᵒᵖ⥤Type uZα:NatTransZZ'x✝¹:Jᵒᵖx✝:Jᵒᵖg:x✝¹⟶x✝w:(F.objPresheafZ).objx✝¹⊢ (ConcreteCategory.hom((F.objPresheafZ).mapg≫↾funw↦⟨F.mapα↑w,⋯⟩)).toFunw=(ConcreteCategory.hom((↾funw↦⟨F.mapα↑w,⋯⟩)≫(F.objPresheafZ').mapg)).toFunwexactSubtype.ext(F.map_objRestrαg.unopw.1w.2)All goals completed! 🐙