/-
Copyright (c) 2026 Terence Rokop. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Terence Rokop
-/modulepublicimportMathlib.Data.PFunctor.Univariate.Basic
Slice polynomial functors on Type (constructive core)
A PFunctor is the middle map of a Gambino–Hyland polynomial diagram
dom ◀ r ─ Idx ─ fst ▶ A ─ q ▶ cod. Adding r : Idx → dom and
q : A → cod yields a polynomial functor Type/dom → Type/cod,
defined as a restriction of the interpretation P.Obj X = Σ a, B a → X
to r-compatible direction assignments, each shape carrying an output
index via q. This is a dependent polynomial functor
[GambinoHyland2004], [GambinoKock2013], equivalently an indexed
container [AltenkirchGhaniHancockMcBrideMorris2015]; that reference
presents it as a two-field (shapes, positions) record with the
indices folded into dependent types, whereas here the index
assignments are the explicit maps q and r. The letters q
(shape-output) and r (direction-input) are this development's; the
polynomial-diagram sources letter the map into cod as t and the
map into dom as s.
This file is the constructive core: the structures, the compatibility
predicate, the curried constructor, and the object/morphism maps with
their functoriality stated as plain equalities. It names no Over and
no CategoryTheory.Functor, so it is Classical.choice-free. The
categorical packaging is in the sibling Slice.Functor module.
Main definitions
SliceDomPFunctor, SlicePFunctor — the structures.
SliceDomPFunctor.Compatible — the direction-compatibility predicate.
SliceDomPFunctor.ofCurried / rCurried — the curried constructor and
the direction-input map in dependently-curried form.
SliceDomPFunctor.DirectionOver / Direction — the direction-input-map
condition on a direction of shape a, and the fiber of rCurried a
over i.
SliceDomPFunctor.Obj / map — the domain-restricted functor's
object and morphism maps; map_id / map_comp its functoriality.
SlicePFunctor.obj / map — the slice functor Type/dom → Type/cod:
obj is the output object's structure map into cod, map the
underlying function; map_w that it lies over cod, map_id /
map_comp its functoriality.
SlicePFunctor.ShapeOver / Shape — the shape-output-map condition and
the fiber of q over j.
SliceDomPFunctor.prod — the product of two slice-domain polynomial
functors; SliceDomPFunctor.representable — the one represented by an
object of Type/dom; SliceDomPFunctor.prodSlice — the product of one
with a SlicePFunctor, formed on the domain side.
SlicePFunctor.coprod — the coproduct of an indexed family of slice
polynomial functors; SlicePFunctor.ofFamily — the one assembled from a
cod-indexed family of SliceDomPFunctors.
SliceDomPFunctor.map_fst — map fixes the shape component.
SliceDomPFunctor.map_id / map_comp — functoriality of the
domain-restricted action.
SlicePFunctor.map_w — the slice morphism lies over cod.
SlicePFunctor.map_id / map_comp — functoriality of the slice functor.
Implementation notes
SliceDomPFunctor.Obj is a subtype of PFunctor.Obj; map is
PFunctor.map restricted; functoriality reuses
PFunctor.id_map / PFunctor.map_map. The SlicePFunctor interpretation
reuses these — its carrier is SliceDomPFunctor.Obj and its map the
SliceDomPFunctor map — adding only the q-assigned output index
(obj) and the output-index compatibility (map_w); map_id /
map_comp delegate to the domain-side ones. SliceDomPFunctor.Obj and
SlicePFunctor.obj, both
namespaces' map,
SliceDomPFunctor.Compatible / ofCurried / rCurried / DirectionOver /
Direction,
and SlicePFunctor.ShapeOver / Shape are @[expose] so the
wrapper and tests can unfold them across the module boundary. The fiber
formers DirectionOver / Direction / ShapeOver / Shape are
additionally @[implicit_reducible]: they occur inside dependent types,
and type-level unification compares types at implicit transparency, so
without the attribute keyed matching fails on terms whose types differ
only by unfolding them.
A direction assignment v : F.B a → X is compatible with a projection
p : X → dom when, as functions F.B a → dom, p ∘ v equals the
direction-input map restricted to shape a. Pointwise: p (v b) = r ⟨a, b⟩.
@[`@[expose]` has no effect outside a `module` fileexpose]defCompatible{dom:TypeuD}(F:SliceDomPFunctor.{uA,uB}dom){X:TypeuX}(p:X→dom)(a:F.A)(v:F.Ba→X):Prop:=p∘v=F.r∘Sigma.mka
Build a SliceDomPFunctor from the dependently-curried
direction-input map.
@[`@[expose]` has no effect outside a `module` fileexpose]defofCurried(P:PFunctor.{uA,uB})(dom:TypeuD)(sc:(a:P.A)→P.Ba→dom):SliceDomPFunctordomwheretoPFunctor:=Pr:=funx↦scx.1x.2
The direction-input map in dependently-curried form.
@[`@[expose]` has no effect outside a `module` fileexpose]defrCurried{dom:TypeuD}(F:SliceDomPFunctor.{uA,uB}dom)(a:F.A)(b:F.Ba):dom:=F.r⟨a,b⟩
The direction-input-map condition on a direction of shape a: that its
image under rCurried a is i. Point-free as (· = i) ∘ rCurried a.
@[`@[expose]` has no effect outside a `module` fileexpose,implicit_reducible]defDirectionOver{dom:TypeuD}(F:SliceDomPFunctor.{uA,uB}dom)(a:F.A)(i:dom):F.Ba→Prop:=(·=i)∘F.rCurrieda
The directions of shape a lying over the base point i: the fiber
of rCurried a over i.
@[`@[expose]` has no effect outside a `module` fileexpose,implicit_reducible]defDirection{dom:TypeuD}(F:SliceDomPFunctor.{uA,uB}dom)(a:F.A)(i:dom):TypeuB:=Subtype(F.DirectionOverai)
The product of two slice-domain polynomial functors: a shape is a pair
of shapes, a direction at that pair is a direction of either factor at its
own component, and the direction-input map is the cotuple of the factors'.
This is the product of the functors Type/dom → Type they interpret,
(Σ a, F.B a → X) × (Σ a', G.B a' → X) being Σ (a, a'), F.B a ⊕ G.B a' → X.
set_optionlinter.checkUnivsfalsein@[`@[expose]` has no effect outside a `module` fileexpose]defprod{dom:TypeuD}(FG:SliceDomPFunctor.{uA,uB,uD}dom):SliceDomPFunctor.{uA,uB,uD}domwheretoPFunctor:=⟨F.toPFunctor.A×G.toPFunctor.A,funx↦F.toPFunctor.Bx.1⊕G.toPFunctor.Bx.2⟩r:=funx↦Sum.elim(funb↦F.r⟨x.1.1,b⟩)(funb↦G.r⟨x.1.2,b⟩)x.2
The slice-domain polynomial functor represented by the object
v : V → dom of Type/dom: one shape, whose directions are V, with v
as the direction-input map. The functor Type/dom → Type it interprets is
Hom_{Type/dom} ((V, v), -), its value at (X, p) being the assignments
f : V → X with p ∘ f = v.
set_optionlinter.checkUnivsfalsein@[`@[expose]` has no effect outside a `module` fileexpose]defrepresentable{dom:TypeuD}(V:TypeuB)(v:V→dom):SliceDomPFunctor.{uA,uB,uD}domwheretoPFunctor:=⟨PUnit,fun_↦V⟩r:=funx↦vx.2
The product of G with a slice polynomial functor F, formed on the
domain side: prod on the SliceDomPFunctors, with F's shape-output map
read off the second shape component. Under the equivalence of Type/cod
with cod-indexed families (SlicePFunctor.ofFamily), this is the
cod-way product of the products of G with each member of F's family;
forming it here avoids the Σ over cod that transporting across the
equivalence would introduce, and with it the raising of the shape universe
by cod's.
set_optionlinter.checkUnivsfalsein@[`@[expose]` has no effect outside a `module` fileexpose]defprodSlice{dom:TypeuD}{cod:TypeuC}(G:SliceDomPFunctor.{uA,uB,uD}dom)(F:SlicePFunctor.{uA,uB,uD,uC}domcod):SlicePFunctor.{uA,uB,uD,uC}domcodwheretoSliceDomPFunctor:=G.prodF.toSliceDomPFunctorq:=funx↦F.qx.2
Value of the domain-restricted functor on (X, p): the
compatibility subtype of the PFunctor interpretation.
@[`@[expose]` has no effect outside a `module` fileexpose]defObj{dom:TypeuD}(F:SliceDomPFunctor.{uA,uB}dom){X:TypeuX}(p:X→dom):Type(maxuAuBuX):={x:F.toPFunctor.ObjX//F.Compatiblepx.1x.2}
Action on a slice morphism f (with p' ∘ f = p): PFunctor.map f
restricted to the compatibility subtype.
@[`@[expose]` has no effect outside a `module` fileexpose]defmap{dom:TypeuD}(F:SliceDomPFunctor.{uA,uB}dom){X:TypeuX}{X':TypeuX'}{p:X→dom}{p':X'→dom}(f:X→X')(hf:p'∘f=p):F.Objp→F.Objp':=funx↦⟨F.toPFunctor.mapfx.1,dom:Type uDF:SliceDomPFunctordomX:Type uXX':Type uX'p:X→domp':X'→domf:X→X'hf:p'∘f=px:F.Objp⊢ F.Compatiblep'(F.mapf↑x).fst(F.mapf↑x).snddom:Type uDF:SliceDomPFunctordomX:Type uXX':Type uX'p:X→domp':X'→domf:X→X'hf:p'∘f=pa:F.Av:F.Ba→Xhx:F.Compatiblep⟨a,v⟩.fst⟨a,v⟩.snd⊢ F.Compatiblep'(F.mapf↑⟨⟨a,v⟩,hx⟩).fst(F.mapf↑⟨⟨a,v⟩,hx⟩).snddom:Type uDF:SliceDomPFunctordomX:Type uXX':Type uX'p:X→domp':X'→domf:X→X'hf:p'∘f=pa:F.Av:F.Ba→Xhx:F.Compatiblep⟨a,v⟩.fst⟨a,v⟩.snd⊢ p'∘f∘v=F.r∘Sigma.mkadom:Type uDF:SliceDomPFunctordomX:Type uXX':Type uX'p:X→domp':X'→domf:X→X'hf:p'∘f=pa:F.Av:F.Ba→Xhx:F.Compatiblep⟨a,v⟩.fst⟨a,v⟩.snd⊢ p∘v=F.r∘Sigma.mkaexacthxAll goals completed! 🐙⟩
The slice functor's value on (X, p), as an object of Type/cod: its
structure map into cod, the shape-output map applied to each shape. The
carrier is the SliceDomPFunctor value F.toSliceDomPFunctor.Obj p.
@[`@[expose]` has no effect outside a `module` fileexpose]defobj{dom:TypeuD}{cod:TypeuC}(F:SlicePFunctor.{uA,uB,uD,uC}domcod){X:TypeuX}(p:X→dom):F.toSliceDomPFunctor.Objp→cod:=funz↦F.qz.1.1
The slice functor's action on a morphism: the SliceDomPFunctor morphism
map underlying it.
@[`@[expose]` has no effect outside a `module` fileexpose]defmap{dom:TypeuD}{cod:TypeuC}(F:SlicePFunctor.{uA,uB,uD,uC}domcod){X:TypeuX}{X':TypeuX'}{p:X→dom}{p':X'→dom}(f:X→X')(hf:p'∘f=p):F.toSliceDomPFunctor.Objp→F.toSliceDomPFunctor.Objp':=F.toSliceDomPFunctor.mapfhf
map lies over cod: it commutes with the obj structure maps.
The shape-output-map condition on a shape: that its image under q
is j. Point-free as (· = j) ∘ q.
@[`@[expose]` has no effect outside a `module` fileexpose,implicit_reducible]defShapeOver{dom:TypeuD}{cod:TypeuC}(F:SlicePFunctor.{uA,uB,uD,uC}domcod)(j:cod):F.A→Prop:=(·=j)∘F.q
The shapes lying over j: the fiber of q over j.
@[`@[expose]` has no effect outside a `module` fileexpose,implicit_reducible]defShape{dom:TypeuD}{cod:TypeuC}(F:SlicePFunctor.{uA,uB,uD,uC}domcod)(j:cod):TypeuA:=Subtype(F.ShapeOverj)
The coproduct of a family of slice polynomial functors indexed by A:
shapes are the disjoint union of the summands' shapes, and the directions,
the direction-input map, and the shape-output map are those of the summand
a shape came from. The index type's universe is independent of the
summands' shape universe, so the result's shape universe is their maximum.
set_optionlinter.checkUnivsfalsein@[`@[expose]` has no effect outside a `module` fileexpose]defcoprod{dom:TypeuD}{cod:TypeuC}(A:TypeuA')(sub:A→SlicePFunctor.{uA,uB,uD,uC}domcod):SlicePFunctor.{maxuA'uA,uB,uD,uC}domcodwheretoPFunctor:=⟨Σa,(suba).toPFunctor.A,funx↦(subx.1).toPFunctor.Bx.2⟩r:=funx↦(subx.1.1).r⟨x.1.2,x.2⟩q:=funx↦(subx.1).qx.2
The slice polynomial functor Type/dom → Type/cod assembled from a
cod-indexed family of functors Type/dom → Type, transporting the family
across the equivalence of Type/cod with cod-indexed families: a shape is
a shape of one member tagged with that member's index, and the shape-output
map returns the tag. It is the coproduct of the members, each given the
constant shape-output map at its own index, so the shape universe rises by
cod's.
set_optionlinter.checkUnivsfalsein@[`@[expose]` has no effect outside a `module` fileexpose]defofFamily{dom:TypeuD}{cod:TypeuC}(fam:cod→SliceDomPFunctor.{uA,uB,uD}dom):SlicePFunctor.{maxuCuA,uB,uD,uC}domcod:=coprodcodfuno↦{toSliceDomPFunctor:=famo,q:=fun_↦o}