3. HomKernel tactic
The hom_kernel tactic is the inverse of kernel_hom. It transforms categorical equalities in the SFinKer category back into equivalent kernel equalities. For example, given morphisms κ.hom ≫ η.hom = ξ.hom in the SFinKer category, the tactic transforms it back to the kernel equality η ∘ₖ κ = ξ.
The tactic can be described in 3 steps:
-
First, it recursively traverses the categorical equality and creates a new expression where each morphism is replaced by its translation as a kernel expression, uniformly un-lifting carrier spaces from the common universe level to their original universe levels using measurable equivalences. During this process, it recognizes patterns of categorical composition and identities, and translates them to the corresponding kernel operations (composition, identity, parallel composition, etc...). This is done using the
transformHomToKernelfunction. -
Next, it constructs the proof of equivalence between the original kernel equality and the transformed categorical equality. This proof relies on the properties of the translation (e.g., that it preserves composition and identities) and on the fact that all kernels can be uniformly lifted to the common universe level using measurable equivalences.
-
Finally, it replaces the original goal or hypothesis with the transformed one.
Note that when PUnit is encountered during the un-lifting process, it un-lifts to Unit, no matter the universe level of the original PUnit carrier. This is because PUnit is used as the unit object of the monoidal structure, which makes it hard to recover the original universe level.
3.1. Usage example
The tactic hom_kernel is complementary to kernel_hom and allows users to bring back categorical equalities to kernel equalities after applying categorical reasoning or categorical tactics.
example (κ η : Kernel X Y) [IsSFiniteKernel κ] [IsSFiniteKernel η]
(h : κ = η) : κ ∘ₖ Kernel.id = η := X:Type u_1Y:Type u_2inst✝³:MeasurableSpace Xinst✝²:MeasurableSpace Yκ:Kernel X Yη:Kernel X Yinst✝¹:IsSFiniteKernel κinst✝:IsSFiniteKernel ηh:κ = η⊢ κ ∘ₖ Kernel.id = η
X:Type u_1Y:Type u_2inst✝³:MeasurableSpace Xinst✝²:MeasurableSpace Yκ:Kernel X Yη:Kernel X Yinst✝¹:IsSFiniteKernel κinst✝:IsSFiniteKernel ηh:κ = η⊢ 𝟙 { carrier := ULift.{max (max (max (u_1 + 1) (u_2 + 1)) u_1) u_2, u_1} X, str := ULift.instMeasurableSpace } ≫ κ.hom =
η.hom
X:Type u_1Y:Type u_2inst✝³:MeasurableSpace Xinst✝²:MeasurableSpace Yκ:Kernel X Yη:Kernel X Yinst✝¹:IsSFiniteKernel κinst✝:IsSFiniteKernel ηh:κ = η⊢ κ.hom = η.hom
X:Type u_1Y:Type u_2inst✝³:MeasurableSpace Xinst✝²:MeasurableSpace Yκ:Kernel X Yη:Kernel X Yinst✝¹:IsSFiniteKernel κinst✝:IsSFiniteKernel ηh:κ = η⊢ κ = η
All goals completed! 🐙