{-# OPTIONS --safe #-} open import Level open import Categories.Category.Core open import Categories.Category.Cocartesian open import Categories.Monad.Construction.Kleisli open import Categories.Monad hiding (id) open import Categories.Monad.Relative renaming (Monad to RMonad) open import Categories.Functor hiding (id) import Categories.Morphism.Reasoning as MR module Monad.Elgot {o ℓ e} {C : Category o ℓ e} (cocartesian : Cocartesian C) where open Category C open Cocartesian cocartesian open import Algebra.Elgot cocartesian open HomReasoning open Equiv open MR C open import Monad.Helper record IsElgot (T : Monad C) : Set (o ⊔ ℓ ⊔ e) where open Monad T using (η; μ; F) open RMonad (Monad⇒Kleisli C T) using (extend; extend-≈) open Functor F renaming (F₀ to T₀; F₁ to T₁) field _† : ∀ {X Y} → (X ⇒ T₀ (Y + X)) → X ⇒ T₀ Y field †-Fixpoint : ∀ {X Y} {f : X ⇒ T₀ (Y + X)} → f † ≈ extend [ η.η _ , f † ] ∘ f †-Naturality : ∀ {X Y Z} {f : X ⇒ T₀ (Y + X)} {g : Y ⇒ T₀ Z} → extend g ∘ f † ≈ (extend [ T₁ i₁ ∘ g , η.η _ ∘ i₂ ] ∘ f) † †-Codiagonal : ∀ {X Y} {f : X ⇒ T₀ ((Y + X) + X)} → (T₁ [ id , i₂ ] ∘ f) † ≈ f † † †-Uniformity : ∀ {X Y Z} {f : X ⇒ T₀ (Y + X)} {g : Z ⇒ T₀ (Y + Z)} {h : Z ⇒ X} → f ∘ h ≈ T₁ (id +₁ h) ∘ g → g † ≈ f † ∘ h †-resp-≈ : ∀ {X Y} {f g : X ⇒ T₀ (Y + X)} → f ≈ g → f † ≈ g † private ∇ : ∀ {X} → X + X ⇒ X ∇ = [ id , id ] †-Diamond : ∀ {X Y} {f : Y ⇒ T₀ (X + Y + Y)} → (T₁ (id +₁ ∇) ∘ f) † ≈ (extend [ η.η _ ∘ i₁ , [ T₁ i₁ ∘ (T₁ (id +₁ ∇) ∘ f) † , η.η _ ∘ i₂ ] ] ∘ f) † †-Diamond {X} {Y} {f} = begin (T₁ (id +₁ ∇) ∘ f) † ≈⟨ helper ⟩ (T₁ [ i₁ ∘ i₁ , i₂ +₁ id ] ∘ f) † † ≈⟨ †-Fixpoint ⟩ extend [ η.η _ , (T₁ [ i₁ ∘ i₁ , i₂ +₁ id ] ∘ f) † † ] ∘ (T₁ [ i₁ ∘ i₁ , i₂ +₁ id ] ∘ f) † ≈˘⟨ (extend-≈ ([]-cong₂ refl helper)) ⟩∘⟨refl ⟩ extend [ η.η _ , (T₁ (id +₁ ∇) ∘ f) † ] ∘ (T₁ [ i₁ ∘ i₁ , i₂ +₁ id ] ∘ f) † ≈⟨ †-Naturality ⟩ (extend [ T₁ i₁ ∘ [ η.η _ , (T₁ (id +₁ ∇) ∘ f) † ] , η.η _ ∘ i₂ ] ∘ T₁ [ i₁ ∘ i₁ , i₂ +₁ id ] ∘ f) † ≈⟨ †-resp-≈ (∘-resp-≈ˡ (extend-≈ ([]-cong₂ (∘[] ○ []-cong₂ (sym (η.commute _)) refl) refl))) ⟩ (extend [ [ η.η _ ∘ i₁ , T₁ i₁ ∘ (T₁ (id +₁ ∇) ∘ f) † ] , η.η _ ∘ i₂ ] ∘ T₁ [ i₁ ∘ i₁ , i₂ +₁ id ] ∘ f) † ≈⟨ †-resp-≈ (pullˡ (extend∘F₁ T _ _ ○ extend-≈ (∘[] ○ []-cong₂ (pullˡ inject₁ ○ inject₁) ([]∘+₁ ○ []-cong₂ inject₂ identityʳ)))) ⟩ (extend [ η.η _ ∘ i₁ , [ T₁ i₁ ∘ (T₁ (id +₁ ∇) ∘ f) † , η.η _ ∘ i₂ ] ] ∘ f) † ∎ where helper : (T₁ (id +₁ ∇) ∘ f) † ≈ (T₁ [ i₁ ∘ i₁ , i₂ +₁ id ] ∘ f) † † helper = begin (T₁ (id +₁ ∇) ∘ f) † ≈⟨ †-resp-≈ (∘-resp-≈ˡ (F-resp-≈ ([]-cong₂ identityʳ (∘[] ○ []-cong₂ identityʳ identityʳ)))) ⟩ (T₁ [ i₁ , [ i₂ , i₂ ] ] ∘ f) † ≈˘⟨ †-resp-≈ (pullˡ (sym homomorphism ○ F-resp-≈ (∘[] ○ []-cong₂ (cancelˡ inject₁) ([]∘+₁ ○ []-cong₂ identityˡ identityʳ)))) ⟩ (T₁ [ id , i₂ ] ∘ T₁ [ i₁ ∘ i₁ , i₂ +₁ id ] ∘ f) † ≈⟨ †-Codiagonal ⟩ (T₁ [ i₁ ∘ i₁ , i₂ +₁ id ] ∘ f) † † ∎ record ElgotMonad : Set (o ⊔ ℓ ⊔ e) where field T : Monad C isElgot : IsElgot T open IsElgot isElgot public