{-# OPTIONS --safe #-}
open import Categories.Category.Core
open import Categories.Category.Distributive
open import Categories.Object.NaturalNumbers.Parametrized
open import Monad.Instance.Delay
open import Monad.Instance.Delay.Quotient
open import Categories.Object.Terminal
open import Categories.Functor.Properties using ([_]-resp-Iso)
import Categories.Morphism as M
import Categories.Morphism.Reasoning as MR
import Categories.Morphism.Properties as MP
module Monad.Instance.Delay.Quotient.Epis {o ℓ e} {C : Category o ℓ e} (distributive : Distributive C) (DM : DelayM (Distributive.cocartesian distributive)) (PNNO : ParametrizedNNO C (Distributive.cartesian distributive)) (DQ : DelayQ distributive DM PNNO) where
open import Categories.Diagram.Coequalizer C
open Category C
open HomReasoning
open Equiv
open import Category.Distributive.Helper distributive
open M C
open MR C
open MP C
open DelayM DM
open D-Monad
open DelayQ DQ
open import Monad.Instance.Delay.Strong distributive DM
open D-Strong
open τ-mod
open import Algebra.Search cocartesian DM
open import Algebra.Search.Retraction distributive DM
open Terminal terminal using (⊤)
epi-Dρ : ∀ {X} → (s-alg-on : Search-Algebra-on (Ď₀ X)) → Epi (D₁ (ρ {X}))
epi-Dρ {X} s-alg-on f g eq = epi₄ f g (epi₃ (f ∘ D₁ π₁) (g ∘ D₁ π₁) (pullʳ helper ○ extendʳ eq ○ pushʳ (sym helper)))
where
s-alg : Search-Algebra
s-alg = record { A = Ď₀ X ; search-algebra-on = s-alg-on }
open Search-Algebra-on s-alg-on
helper : D₁ π₁ ∘ D₁ (ρ ⁂ id) ≈ D₁ ρ ∘ D₁ π₁
helper = sym D.F.homomorphism ○ D.F.F-resp-≈ project₁ ○ D.F.homomorphism
epi₁ : ∀ {Y} → Epi (ρ {X} ⁂ id {Y})
epi₁ {Y} = IsCoequalizer⇒Epi (coeq-productsˡ (id {Y}))
epi₂ : Epi (τ ∘ (ρ {X} ⁂ id {D₀ ⊤}))
epi₂ f g eq = begin
f ≈⟨ introʳ (Retract.is-retract (tau-retract (⊤) s-alg)) ⟩
f ∘ τ ∘ ⟨ α ∘ D₁ π₁ , D₁ π₂ ⟩ ≈⟨ extendʳ (epi₁ (f ∘ τ) (g ∘ τ) (assoc ○ eq ○ sym-assoc)) ⟩
g ∘ τ ∘ ⟨ α ∘ D₁ π₁ , D₁ π₂ ⟩ ≈˘⟨ introʳ (Retract.is-retract (tau-retract (⊤) s-alg)) ⟩
g ∎
epi₃ : Epi (D₁ (ρ ⁂ id))
epi₃ f g eq = epi₂ f g (begin
f ∘ τ ∘ (ρ ⁂ id) ≈⟨ refl⟩∘⟨ epi₃-helper ⟩
f ∘ D₁ (ρ ⁂ id) ∘ τ ≈⟨ extendʳ eq ⟩
g ∘ D₁ (ρ ⁂ id) ∘ τ ≈˘⟨ refl⟩∘⟨ epi₃-helper ⟩
g ∘ τ ∘ (ρ ⁂ id) ∎)
where
epi₃-helper : τ ∘ (ρ ⁂ id) ≈ D₁ (ρ ⁂ id) ∘ τ
epi₃-helper = begin
τ ∘ (ρ ⁂ id) ≈⟨ refl⟩∘⟨ ⁂-cong₂ refl (sym D.F.identity) ⟩
τ ∘ (ρ ⁂ D₁ id) ≈⟨ τ-natural ρ id ⟩
D₁ (ρ ⁂ id) ∘ τ ∎
epi₄ : Epi (D₁ (π₁ {Ď₀ X} {⊤}))
epi₄ = Iso⇒Epi ([ D.F ]-resp-Iso (_≅_.iso A×⊤≅A))
epi-DDρ : ∀ {X} → (s-alg-on : Search-Algebra-on (Ď₀ X)) → Epi (D₁ (D₁ (ρ {X})))
epi-DDρ {X} s-alg-on f g eq = epi₄ f g (epi₃ (f ∘ D₁ (D₁ π₁)) (g ∘ D₁ (D₁ π₁)) (pullʳ helper ○ extendʳ eq ○ pushʳ (sym helper)))
where
s-alg : Search-Algebra
s-alg = record { A = Ď₀ X ; search-algebra-on = s-alg-on }
open Search-Algebra-on s-alg-on
helper : D₁ (D₁ π₁) ∘ D₁ (D₁ (ρ ⁂ id)) ≈ D₁ (D₁ ρ) ∘ D₁ (D₁ π₁)
helper = begin
D₁ (D₁ π₁) ∘ D₁ (D₁ (ρ ⁂ id)) ≈⟨ sym D.F.homomorphism ⟩
D₁ (D₁ π₁ ∘ D₁ (ρ ⁂ id)) ≈⟨ D.F.F-resp-≈ (sym D.F.homomorphism) ⟩
D₁ (D₁ (π₁ ∘ (ρ ⁂ id))) ≈⟨ D.F.F-resp-≈ (D.F.F-resp-≈ project₁) ⟩
D₁ (D₁ (ρ ∘ π₁)) ≈⟨ D.F.F-resp-≈ D.F.homomorphism ⟩
D₁ (D₁ ρ ∘ D₁ π₁) ≈⟨ D.F.homomorphism ⟩
D₁ (D₁ ρ) ∘ D₁ (D₁ π₁) ∎
epi₁ : ∀ {Y} → Epi (ρ {X} ⁂ id {Y})
epi₁ {Y} = IsCoequalizer⇒Epi (coeq-productsˡ (id {Y}))
epi₂ : Epi (D₁ τ ∘ τ ∘ (ρ {X} ⁂ id {D₀ (D₀ (Terminal.⊤ terminal))}))
epi₂ f g eq = begin
f ≈⟨ introʳ (D.F.F-resp-≈ (Retract.is-retract (tau-retract (Terminal.⊤ terminal) s-alg)) ○ D.F.identity) ⟩
f ∘ D₁ (τ ∘ ⟨ α ∘ D₁ π₁ , D₁ π₂ ⟩) ≈⟨ refl⟩∘⟨ D.F.homomorphism ⟩
f ∘ D₁ τ ∘ D₁ ⟨ α ∘ D₁ π₁ , D₁ π₂ ⟩ ≈⟨ refl⟩∘⟨ refl⟩∘⟨ insertˡ (Retract.is-retract (tau-retract (D₀ (Terminal.⊤ terminal)) s-alg)) ⟩
f ∘ D₁ τ ∘ τ ∘ ⟨ α ∘ D₁ π₁ , D₁ π₂ ⟩ ∘ D₁ ⟨ α ∘ D₁ π₁ , D₁ π₂ ⟩ ≈⟨ assoc²εβ ○ ∘-resp-≈ˡ (epi₁ (f ∘ D₁ τ ∘ τ) (g ∘ D₁ τ ∘ τ) (assoc²βε ○ eq ○ assoc²εβ)) ○ assoc²βε ⟩
g ∘ D₁ τ ∘ τ ∘ ⟨ α ∘ D₁ π₁ , D₁ π₂ ⟩ ∘ D₁ ⟨ α ∘ D₁ π₁ , D₁ π₂ ⟩ ≈˘⟨ refl⟩∘⟨ refl⟩∘⟨ insertˡ (Retract.is-retract (tau-retract (D₀ (Terminal.⊤ terminal)) s-alg)) ⟩
g ∘ D₁ τ ∘ D₁ ⟨ α ∘ D₁ π₁ , D₁ π₂ ⟩ ≈˘⟨ refl⟩∘⟨ D.F.homomorphism ⟩
g ∘ D₁ (τ ∘ ⟨ α ∘ D₁ π₁ , D₁ π₂ ⟩) ≈˘⟨ introʳ (D.F.F-resp-≈ (Retract.is-retract (tau-retract (Terminal.⊤ terminal) s-alg)) ○ D.F.identity) ⟩
g ∎
epi₃ : Epi (D₁ (D₁ (ρ ⁂ id)))
epi₃ f g eq = epi₂ f g (begin
f ∘ D₁ τ ∘ τ ∘ (ρ ⁂ id) ≈⟨ refl⟩∘⟨ epi₃-helper ⟩
f ∘ D₁ (D₁ (ρ ⁂ id)) ∘ D₁ τ ∘ τ ≈⟨ extendʳ eq ⟩
g ∘ D₁ (D₁ (ρ ⁂ id)) ∘ D₁ τ ∘ τ ≈˘⟨ refl⟩∘⟨ epi₃-helper ⟩
g ∘ D₁ τ ∘ τ ∘ (ρ ⁂ id) ∎)
where
epi₃-helper : D₁ τ ∘ τ ∘ (ρ ⁂ id) ≈ D₁ (D₁ (ρ ⁂ id)) ∘ D₁ τ ∘ τ
epi₃-helper = begin
D₁ τ ∘ τ ∘ (ρ ⁂ id) ≈⟨ refl⟩∘⟨ refl⟩∘⟨ ⁂-cong₂ refl (sym D.F.identity) ⟩
D₁ τ ∘ τ ∘ (ρ ⁂ D₁ id) ≈⟨ refl⟩∘⟨ τ-natural ρ id ⟩
D₁ τ ∘ D₁ (ρ ⁂ id) ∘ τ ≈⟨ pullˡ (sym D.F.homomorphism) ⟩
D₁ (τ ∘ (ρ ⁂ id)) ∘ τ ≈⟨ (D.F.F-resp-≈ (∘-resp-≈ʳ (⁂-cong₂ refl (sym D.F.identity)))) ⟩∘⟨refl ⟩
D₁ (τ ∘ (ρ ⁂ D₁ id)) ∘ τ ≈⟨ (D.F.F-resp-≈ (τ-natural ρ id)) ⟩∘⟨refl ⟩
D₁ (D₁ (ρ ⁂ id) ∘ τ) ∘ τ ≈⟨ pushˡ D.F.homomorphism ⟩
D₁ (D₁ (ρ ⁂ id)) ∘ D₁ τ ∘ τ ∎
epi₄ : Epi (D₁ (D₁ (π₁ {Ď₀ X} {⊤})))
epi₄ = Iso⇒Epi ([ D.F ]-resp-Iso ([ D.F ]-resp-Iso (_≅_.iso A×⊤≅A)))