Zulip Chat Archive

Stream: mathlib4

Topic: Strong monads


Jad Ghalayini (Feb 13 2025 at 17:19):

Does it make sense to add a PR for a StrongMonad C class, which extends Monad C with data ensuring the monad is strong w.r.t. a MonoidalCategory C?

Jad Ghalayini (Feb 13 2025 at 17:20):

We'd also want an instance or somesuch stating that type-monads are always strong

Jad Ghalayini (Feb 13 2025 at 18:47):

Alright here's what I've got so far:

import Mathlib.CategoryTheory.Monad.Basic
import Mathlib.CategoryTheory.Monoidal.Category
import Mathlib.CategoryTheory.Monoidal.Types.Basic

namespace CategoryTheory

variable {C : Type u} [Category C] [MonoidalCategoryStruct C]

open MonoidalCategory

class LeftStrength (T : Monad C) where
  leftStrength : (X Y : C), X  (T.obj Y)  T.obj (X  Y)
  leftStrength_naturality : (X Y X' Y' : C) (f : X  X') (g : Y  Y'),
    (f  (T.map g))  leftStrength X' Y' = leftStrength X Y  T.map (f  g)
  leftUnitor_leftStrength : (X : C),
    (λ_ (T.obj X)).inv  leftStrength (𝟙_ C) X = T.map (λ_ X).inv
  leftStrength_associator : (X Y Z : C),
    leftStrength (X  Y) Z  T.map (α_ X Y Z).hom
      = (α_ X Y (T.obj Z)).hom  X  leftStrength Y Z  leftStrength X (Y  Z)
  η_leftStrength : (X Y : C), X  T.η.app Y  leftStrength X Y = T.η.app (X  Y)
  μ_leftStrength : (X Y : C),
    X  T.μ.app Y  leftStrength X Y
      = leftStrength X (T.obj Y)  T.map (leftStrength X Y)  T.μ.app (X  Y)

attribute [reassoc] LeftStrength.leftStrength_naturality
attribute [reassoc] LeftStrength.leftUnitor_leftStrength
attribute [reassoc] LeftStrength.leftStrength_associator
attribute [reassoc] LeftStrength.η_leftStrength
attribute [reassoc] LeftStrength.μ_leftStrength

class RightStrength (T : Monad C) where
  rightStrength : (X Y : C), T.obj X  Y  T.obj (X  Y)
  rightStrength_naturality : (X Y X' Y' : C) (f : X  X') (g : Y  Y'),
    ((T.map f)  g)  rightStrength X' Y' = rightStrength X Y  T.map (f  g)
  rightUnitor_rightStrength : (X : C),
    (ρ_ (T.obj X)).inv  rightStrength X (𝟙_ C) = T.map (ρ_ X).inv
  rightStrength_associator : (X Y Z : C),
    rightStrength X (Y  Z)  T.map (α_ X Y Z).inv
      = (α_ (T.obj X) Y Z).inv  rightStrength X Y  Z  rightStrength (X  Y) Z
  η_rightStrength : (X Y : C), T.η.app X  Y  rightStrength X Y = T.η.app (X  Y)
  μ_rightStrength : (X Y : C),
    T.μ.app X  Y  rightStrength X Y
      = rightStrength (T.obj X) Y  T.map (rightStrength X Y)  T.μ.app (X  Y)

attribute [reassoc] RightStrength.rightStrength_naturality
attribute [reassoc] RightStrength.rightUnitor_rightStrength
attribute [reassoc] RightStrength.rightStrength_associator
attribute [reassoc] RightStrength.η_rightStrength
attribute [reassoc] RightStrength.μ_rightStrength

class Strength (T : Monad C) extends LeftStrength T, RightStrength T where
  leftStrength_rightStrength : (X Y Z : C),
    leftStrength X Y  Z  rightStrength (X  Y) Z
      = (α_ X (T.obj Y) Z).hom
       X  rightStrength Y Z
       leftStrength X (Y  Z)
       T.map (α_ X Y Z).inv

attribute [reassoc] Strength.leftStrength_rightStrength

open LeftStrength RightStrength

@[reassoc]
theorem Strength.rightStrength_leftStrength {T : Monad C} [Strength T] (X Y Z : C) :
  X  rightStrength Y Z  leftStrength X (Y  Z)
    = (α_ X (T.obj Y) Z).inv  leftStrength X Y  Z  rightStrength _ Z  T.map (α_ X Y Z).hom
  := by simp [leftStrength_rightStrength_assoc]

instance Strength.ofType.{v} {T : Monad (Type v)} : Strength T := /- snip -/

class CommutativeMonad (T : Monad C) extends Strength T where
  is_commutative : (X Y : C),
    leftStrength (T.obj X) Y  T.map (rightStrength X Y)  T.μ.app (X  Y)
      = rightStrength X (T.obj Y)  T.map (leftStrength X Y)  T.μ.app (X  Y)

end CategoryTheory

How does this look for a start?

Jad Ghalayini (Feb 13 2025 at 18:47):

Also, any idea where we might put the analogue of CommutativeMonad for regular type-valued monads?

Jad Ghalayini (Feb 13 2025 at 19:23):

Here's what that would look like btw:

import Mathlib.Tactic.Convert

class SeqComm (f : Type u  Type v) [Applicative f] : Prop where
  seq_comm {α β : Type u} (l : f α) (r : f β) :
    Prod.mk <$> l <*> r = (λr (l : α) => (l, r)) <$> r <*> l

theorem SeqComm.bind_pair_comm {m : Type u  Type v} [Monad m] [LawfulMonad m] [SeqComm m]
  {α β : Type u} (l : m α) (r : m β) :
  (do let l <- l; let r <- r; return (l, r)) = (do let r <- r; let l <- l; return (l, r)) := by
  convert SeqComm.seq_comm l r using 1 <;>
  simp [seq_eq_bind_map]

theorem SeqComm.bind_comm {m : Type u  Type v} [Monad m] [LawfulMonad m] [SeqComm m]
  {α β : Type u} (l : m α) (r : m β) (f : α  β  m γ) :
  (do let l <- l; let r <- r; f l r) = (do let r <- r; let l <- l; f l r) := calc
  _ = (do let l <- l; let r <- r; pure (l, r)) >>= (λ(l, r) => f l r) := by simp
  _ = _ := by rw [bind_pair_comm]; simp

Then any monad satisfying SeqComm (e.g. Option) would satisfy CommutativeMonad as well

Bhavik Mehta (Feb 13 2025 at 19:41):

I'd say strong monads are worth having from a mathematical point of view. I don't know if CommutativeMonad for type-valued monads are worth having: my inclination is that those would be valuable only if they're useful from a programming point of view.

Jad Ghalayini (Feb 13 2025 at 19:44):

Bhavik Mehta said:

I'd say strong monads are worth having from a mathematical point of view. I don't know if CommutativeMonad for type-valued monads are worth having: my inclination is that those would be valuable only if they're useful from a programming point of view.

Commutative monads should be useful for reasoning about programs since they allow re-ordering statements which do not share variables; a few good examples of such monads are Option, ReaderT, and WriterT when the underlying monoid is commutative.

For math, commutative monads give a lot of useful theorems; my goal is to show that strong monads induce a premonoidal category (PR https://github.com/leanprover-community/mathlib4/pull/21488) while commutative monads induce a monoidal category. Going further, a lot of linear algebra can be very elegantly derived from the fact that the free vector space monad is commutative; would be fun to see how this looks in general

Bhavik Mehta (Feb 13 2025 at 19:51):

I completely agree there are a lot of interesting theorems that could be proved for commutative monads!

Jad Ghalayini (Feb 13 2025 at 19:51):

Think it's worth it to put in a PR with what I've got now?

Jad Ghalayini (Feb 13 2025 at 19:52):

So just the strong monad stuff, and some little lemmas?

Bhavik Mehta (Feb 13 2025 at 19:54):

I'd say the strong monad stuff is worth a PR, yeah.

Kim Morrison (Feb 14 2025 at 08:42):

I'm a bit confused why everything is a class above.

Jad Ghalayini (Feb 14 2025 at 13:54):

@Kim Morrison tbf the main application I was thinking of was automatically instantiating things for monads over Set, and other similar cases

Jad Ghalayini (Feb 14 2025 at 13:54):

Eventually what I would like are theorems relating strong monads to monoidal/premonoidal categories


Last updated: May 02 2025 at 03:31 UTC