{-# OPTIONS --lossy-unification #-} open import Level open import Categories.Category.Core open import Categories.Functor hiding (id) open import Categories.Monad hiding (id) open import Categories.Monad.Construction.Kleisli open import Categories.Monad.Relative renaming (Monad to RMonad) open import Data.Product using (_,_; Σ; Σ-syntax) open import Categories.Functor.Algebra open import Categories.Functor.Coalgebra open import Categories.Object.Terminal open import Categories.NaturalTransformation.Core hiding (id) open import Object.FreeObject open import Categories.Category.Distributive open import Categories.Object.NaturalNumbers.Parametrized open import Categories.Functor.Properties using ([_]-resp-Iso) open import Categories.Category.Construction.EilenbergMoore using (Module) open import Categories.Monad.Strong open import Monad.Instance.Delay open import Monad.Instance.Delay.Quotient import Categories.Morphism as M import Categories.Morphism.Reasoning as MR import Categories.Morphism.Properties as MP module Monad.Instance.Delay.Quotient.Theorem.Condition2-3 {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 import Category.Distributive.Helper distributive open Bundles open import Algebra.Elgot cocartesian open import Algebra.Elgot.Free cocartesian open import Algebra.Elgot.Stable distributive open F-Coalgebra-Morphism using () renaming (f to u; commutes to coalg-commutes) open DelayM DM open import Monad.Instance.Delay.Strong distributive DM open D-Kleisli open D-Monad open D-Strong open Coit open τ-mod open ParametrizedNNO PNNO hiding (η) open import Algebra.Search cocartesian DM open import Category.Construction.ElgotAlgebras cocartesian open import Algebra.Search.Retraction distributive DM open HomReasoning open M C open MR C open MP C using (Iso⇒Epi; Iso-swap; Iso⇒Mono) open Equiv open import Monad.Instance.Delay.Iota distributive DM PNNO open import Algebra.Search.Properties cocartesian open DelayQ DQ open import Monad.Instance.Delay.Quotient.Theorem.Conditions distributive DM PNNO DQ open import Monad.Helper open import Algebra.Elgot.MoreProperties distributive DM PNNO open IsFreeObject open Elgot-Algebra-Morphism using () renaming (h to EA-h; preserves to EA-preserves) open import Monad.Instance.Delay.Quotient.Epis distributive DM PNNO DQ open cond-3 private elgot' : ∀ {X} → cond-2 X → Elgot-Algebra-on (Ď₀ X) elgot' {X} c-2 = D-Algebra+Search⇒Elgot DM (record { A = Ď₀ X ; action = α ; commute = epi-DDρ s-alg-on (α ∘ D₁ α) (α ∘ extend (id)) (sym epi-helper) ; identity = identity₁ }) (Search-Algebra-on⇒IsSearchAlgebra s-alg-on) where open cond-2 c-2 renaming (ρ-algebra-morphism to ρ-algebra-morphism-2) open Search-Algebra-on s-alg-on s-alg : Search-Algebra s-alg = record { A = Ď₀ X ; search-algebra-on = s-alg-on } μ∘Dμ : ∀ {X} → D.μ.η X ∘ D.μ.η (D₀ X) ≈ D.μ.η X ∘ D₁ (D.μ.η X) μ∘Dμ {X} = begin D.μ.η X ∘ D.μ.η (D₀ X) ≈⟨ sym DK.assoc ⟩ extend (extend id ∘ id) ≈⟨ extend-≈ identityʳ ⟩ extend (extend id) ≈⟨ extend-≈ (introˡ DK.identityʳ) ⟩ extend ((extend id ∘ now) ∘ extend id) ≈⟨ extend-≈ assoc ⟩ extend (extend id ∘ now ∘ extend id) ≈⟨ DK.assoc ⟩ D.μ.η X ∘ D₁ (D.μ.η X) ∎ epi-helper : (α ∘ D.μ.η (Ď₀ X)) ∘ D₁ (D₁ ρ) ≈ (α ∘ D₁ α) ∘ D₁ (D₁ ρ) epi-helper = begin (α ∘ D.μ.η (Ď₀ X)) ∘ D₁ (D₁ ρ) ≈⟨ pullʳ (D.μ.commute ρ) ⟩ α ∘ D₁ ρ ∘ D.μ.η (D₀ X) ≈⟨ pullˡ (sym ρ-algebra-morphism-2) ⟩ (ρ ∘ D.μ.η X) ∘ D.μ.η (D₀ X) ≈⟨ pullʳ μ∘Dμ ⟩ ρ ∘ D.μ.η X ∘ D₁ (D.μ.η X) ≈⟨ pullˡ ρ-algebra-morphism-2 ⟩ (α ∘ D₁ ρ) ∘ D₁ (D.μ.η X) ≈⟨ pullʳ (sym D.F.homomorphism) ⟩ α ∘ D₁ (ρ ∘ D.μ.η X) ≈⟨ (refl⟩∘⟨ (D.F.F-resp-≈ ρ-algebra-morphism-2)) ⟩ α ∘ D₁ (α ∘ D₁ ρ) ≈⟨ (refl⟩∘⟨ D.F.homomorphism) ⟩ α ∘ D₁ α ∘ D₁ (D₁ ρ) ≈⟨ sym-assoc ⟩ (α ∘ D₁ α) ∘ D₁ (D₁ ρ) ∎ module Stable (X : Obj) (c-2 : ∀ Y → cond-2 Y) where open cond-2 (c-2 X) renaming (ρ-algebra-morphism to ρ-algebra-morphism-2) open Search-Algebra-on s-alg-on using (α) abstract ρ-law' : ρ ≈ α ∘ coit ((ρ ∘ now +₁ id) ∘ out) ρ-law' = begin ρ ≈⟨ introʳ D.identityˡ ⟩ ρ ∘ D.μ.η _ ∘ D₁ now ≈⟨ extendʳ ρ-algebra-morphism-2 ⟩ α ∘ D₁ ρ ∘ D₁ now ≈˘⟨ refl⟩∘⟨ D.F.homomorphism ⟩ α ∘ D₁ (ρ ∘ now) ≈˘⟨ refl⟩∘⟨ coit-unique ((ρ ∘ now +₁ id) ∘ out) (D₁ (ρ ∘ now)) coit-helper ⟩ α ∘ coit ((ρ ∘ now +₁ id) ∘ out) ∎ where coit-helper : out {Ď₀ X} ∘ D₁ {X} {Ď₀ X} (ρ ∘ now {X}) ≈ (id +₁ D₁ (ρ ∘ now)) ∘ (ρ ∘ now +₁ id) ∘ out coit-helper = begin out {Ď₀ X} ∘ D₁ {X} {Ď₀ X} (ρ ∘ now) ≈⟨ D₁-commutes (ρ ∘ now) ⟩ (ρ ∘ now +₁ D₁ (ρ ∘ now)) ∘ out ≈˘⟨ pullˡ (+₁∘+₁ ○ +₁-cong₂ identityˡ identityʳ) ⟩ (id {Ď₀ X} +₁ D₁ (ρ ∘ now)) ∘ (ρ ∘ now +₁ id) ∘ out ∎ module _ {Y : Obj} (EA : Elgot-Algebra) (f : Y × X ⇒ Elgot-Algebra.A EA) where open IsCoequalizer (coeq-productsʳ {X} {Y} (id {Y})) using () renaming (coequalize to prod-coequalize; universal to prod-universal) open Search-Algebra (Elgot⇒Search DM EA) using (A) renaming (α to a) open Module (Elgot⇒D-Algebra DM EA) abstract f-coequalize : (a ∘ D₁ f ∘ τ) ∘ (id ⁂ extend ι) ≈ (a ∘ D₁ f ∘ τ) ∘ (id ⁂ D₁ π₁) f-coequalize = begin (a ∘ D₁ f ∘ τ) ∘ (id ⁂ extend ι) ≈⟨ pullʳ (pullʳ help) ⟩ a ∘ D₁ f ∘ extend ι ∘ D₁ assocʳ ∘ τ ≈˘⟨ refl⟩∘⟨ extendʳ (extend∘F₁' kleisli ι (f ⁂ id) ○ extend-≈ (ι-natural f) ○ sym (F₁∘extend' kleisli f ι)) ⟩ a ∘ extend ι ∘ D₁ (f ⁂ id) ∘ D₁ assocʳ ∘ τ ≈⟨ extendʳ (α-coequalize EA) ⟩ a ∘ D₁ π₁ ∘ D₁ (f ⁂ id) ∘ D₁ assocʳ ∘ τ ≈⟨ refl⟩∘⟨ extendʳ (sym D.F.homomorphism ○ D.F.F-resp-≈ project₁ ○ D.F.homomorphism) ⟩ a ∘ D₁ f ∘ D₁ π₁ ∘ D₁ assocʳ ∘ τ ≈˘⟨ refl⟩∘⟨ refl⟩∘⟨ pushˡ D.F.homomorphism ⟩ a ∘ D₁ f ∘ D₁ (π₁ ∘ assocʳ) ∘ τ ≈⟨ refl⟩∘⟨ refl⟩∘⟨ ((D.F.F-resp-≈ (project₁ ○ ⟨⟩-cong₂ (sym identityˡ) refl)) ⟩∘⟨refl) ⟩ a ∘ D₁ f ∘ D₁ (id ⁂ π₁) ∘ τ ≈˘⟨ pullʳ (pullʳ (τ-natural id π₁)) ⟩ (a ∘ D₁ f ∘ τ) ∘ (id ⁂ D₁ π₁) ∎ where τ-ι : ∀ {X Y} → τ {X} {Y} ∘ (id ⁂ ι {Y}) ≈ ι {X × Y} ∘ assocʳ τ-ι {X} {Y} = Iso⇒Epi (Iso-swap (_≅_.iso ×-assoc)) (τ ∘ (id ⁂ ι)) (ι ∘ assocʳ) (begin (τ ∘ (id ⁂ ι)) ∘ assocˡ ≈⟨ pullʳ (⁂∘⟨⟩ ○ ⟨⟩-cong₂ identityˡ refl) ⟩ τ ∘ ⟨ π₁ ∘ π₁ , ι ∘ ⟨ π₂ ∘ π₁ , π₂ ⟩ ⟩ ≈˘⟨ ι-unique (τ ∘ ⟨ π₁ ∘ π₁ , ι ∘ ⟨ π₂ ∘ π₁ , π₂ ⟩ ⟩) IB₁ IS₁ ⟩ ι ≈˘⟨ cancelʳ assocʳ∘assocˡ ⟩ (ι ∘ assocʳ) ∘ assocˡ ∎) where IB₁ : (τ {X} {Y} ∘ ⟨ π₁ ∘ π₁ , ι ∘ ⟨ π₂ ∘ π₁ , π₂ ⟩ ⟩) ∘ ⟨ id , z ∘ Terminal.! terminal ⟩ ≈ now IB₁ = begin (τ ∘ ⟨ π₁ ∘ π₁ , ι ∘ ⟨ π₂ ∘ π₁ , π₂ ⟩ ⟩) ∘ ⟨ id , z ∘ Terminal.! terminal ⟩ ≈⟨ pullʳ (⟨⟩∘ ○ ⟨⟩-cong₂ (cancelʳ project₁) (pullʳ (⟨⟩∘ ○ ⟨⟩-cong₂ (cancelʳ project₁) project₂))) ⟩ τ ∘ ⟨ π₁ , ι ∘ ⟨ π₂ , z ∘ Terminal.! terminal ⟩ ⟩ ≈˘⟨ refl⟩∘⟨ ⟨⟩-cong₂ refl (∘-resp-≈ʳ (⟨⟩∘ ○ ⟨⟩-cong₂ identityˡ (pullʳ (sym (Terminal.!-unique terminal (Terminal.! terminal ∘ π₂)))))) ⟩ τ ∘ ⟨ π₁ , ι ∘ ⟨ id , z ∘ Terminal.! terminal ⟩ ∘ π₂ ⟩ ≈⟨ (refl⟩∘⟨ (⟨⟩-cong₂ refl (pullˡ ι-zero))) ⟩ τ ∘ ⟨ π₁ , now ∘ π₂ ⟩ ≈˘⟨ (refl⟩∘⟨ (⟨⟩-cong₂ identityˡ refl)) ⟩ τ ∘ (id ⁂ now) ≈⟨ τ-now ⟩ now ∎ IS₁ : (τ {X} {Y} ∘ ⟨ π₁ ∘ π₁ , ι ∘ ⟨ π₂ ∘ π₁ , π₂ ⟩ ⟩) ∘ (id ⁂ s) ≈ later ∘ τ ∘ ⟨ π₁ ∘ π₁ , ι ∘ ⟨ π₂ ∘ π₁ , π₂ ⟩ ⟩ IS₁ = begin (τ ∘ ⟨ π₁ ∘ π₁ , ι ∘ ⟨ π₂ ∘ π₁ , π₂ ⟩ ⟩) ∘ (id ⁂ s) ≈⟨ pullʳ (⟨⟩∘ ○ ⟨⟩-cong₂ (pullʳ (project₁ ○ identityˡ)) (pullʳ (⟨⟩∘ ○ ⟨⟩-cong₂ (pullʳ (project₁ ○ identityˡ)) project₂))) ⟩ τ ∘ ⟨ π₁ ∘ π₁ , ι ∘ ⟨ π₂ ∘ π₁ , s ∘ π₂ ⟩ ⟩ ≈˘⟨ (refl⟩∘⟨ (⟨⟩-cong₂ refl (refl⟩∘⟨ (⁂∘⟨⟩ ○ ⟨⟩-cong₂ identityˡ refl)))) ⟩ τ ∘ ⟨ π₁ ∘ π₁ , ι ∘ (id ⁂ s) ∘ ⟨ π₂ ∘ π₁ , π₂ ⟩ ⟩ ≈⟨ (refl⟩∘⟨ (⟨⟩-cong₂ refl (extendʳ ι-succ))) ⟩ τ ∘ ⟨ π₁ ∘ π₁ , later ∘ ι ∘ ⟨ π₂ ∘ π₁ , π₂ ⟩ ⟩ ≈˘⟨ (refl⟩∘⟨ (⁂∘⟨⟩ ○ ⟨⟩-cong₂ identityˡ refl)) ⟩ τ ∘ (id ⁂ later) ∘ ⟨ π₁ ∘ π₁ , ι ∘ ⟨ π₂ ∘ π₁ , π₂ ⟩ ⟩ ≈⟨ extendʳ τ-later ⟩ later ∘ τ ∘ ⟨ π₁ ∘ π₁ , ι ∘ ⟨ π₂ ∘ π₁ , π₂ ⟩ ⟩ ∎ help : τ {Y} {X} ∘ (id ⁂ extend ι) ≈ extend ι ∘ D₁ assocʳ ∘ τ help = begin τ ∘ (id ⁂ extend ι) ≈˘⟨ refl⟩∘⟨ (⁂∘⁂ ○ ⁂-cong₂ identity² (sym (extend⇒F₁ kleisli ι))) ⟩ τ ∘ (id ⁂ D.μ.η _) ∘ (id ⁂ D₁ ι) ≈⟨ extendʳ (sym strength.μ-η-comm) ⟩ D.μ.η _ ∘ (D₁ τ ∘ τ) ∘ (id ⁂ D₁ ι) ≈⟨ refl⟩∘⟨ pullʳ (τ-natural id ι) ⟩ D.μ.η _ ∘ D₁ τ ∘ D₁ (id ⁂ ι) ∘ τ ≈⟨ refl⟩∘⟨ (extendʳ (sym D.F.homomorphism ○ D.F.F-resp-≈ τ-ι ○ D.F.homomorphism)) ⟩ D.μ.η _ ∘ D₁ ι ∘ D₁ assocʳ ∘ τ ≈˘⟨ pushˡ (extend⇒F₁ kleisli ι) ⟩ extend ι ∘ D₁ assocʳ ∘ τ ∎ abstract [_,_]♯' : ∀ {Y} (EA : Elgot-Algebra) → Y × X ⇒ Elgot-Algebra.A EA → Y × Ď₀ X ⇒ Elgot-Algebra.A EA [_,_]♯' {Y} EA f = prod-coequalize {h = a ∘ D₁ f ∘ τ} (f-coequalize EA f) where open IsCoequalizer (coeq-productsʳ {X} {Y} (id {Y})) using () renaming (coequalize to prod-coequalize; universal to prod-universal) open Search-Algebra (Elgot⇒Search DM EA) using (A) renaming (α to a) open Module (Elgot⇒D-Algebra DM EA) ♯-law' : ∀ {Y} {EA : Elgot-Algebra} (f : Y × X ⇒ Elgot-Algebra.A EA) → f ≈ [ EA , f ]♯' ∘ (id ⁂ ρ ∘ now) ♯-law' {Y} {EA} f = begin f ≈⟨ insertˡ identity₁ ⟩ a ∘ now ∘ f ≈˘⟨ refl⟩∘⟨ DK.identityʳ ⟩ a ∘ D₁ f ∘ now ≈˘⟨ refl⟩∘⟨ refl⟩∘⟨ τ-now ⟩ a ∘ D₁ f ∘ τ ∘ (id ⁂ now) ≈˘⟨ (pullˡ (sym (prod-universal {eq = f-coequalize EA f})) ○ assoc²βε) ⟩ prod-coequalize (f-coequalize EA f) ∘ (id ⁂ ρ) ∘ (id ⁂ now) ≈⟨ refl⟩∘⟨ (⁂∘⁂ ○ ⁂-cong₂ identity² refl) ⟩ prod-coequalize (f-coequalize EA f) ∘ (id ⁂ ρ ∘ now) ∎ where open IsCoequalizer (coeq-productsʳ {X} {Y} (id {Y})) using () renaming (coequalize to prod-coequalize; universal to prod-universal) open Search-Algebra (Elgot⇒Search DM EA) using (A; identity₁) renaming (α to a) open Module (Elgot⇒D-Algebra DM EA) ♯-unique' : ∀ {Y} {EA : Elgot-Algebra} (f : Y × X ⇒ Elgot-Algebra.A EA) (g : Y × Ď₀ X ⇒ Elgot-Algebra.A EA) → f ≈ g ∘ (id ⁂ ρ ∘ now) → (∀ {Z} {h : Z ⇒ Ď₀ X + Z} → g ∘ (id ⁂ Search-Algebra-on.α s-alg-on ∘ coit h) ≈ Elgot-Algebra._# EA ((g +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ h))) → g ≈ [ EA , f ]♯' ♯-unique' {Y} {EA} f g g-law g-preserving = prod-unique (sym (begin g ∘ (id ⁂ ρ) ≈⟨ refl⟩∘⟨ (⁂-cong₂ refl ρ-law') ⟩ g ∘ (id ⁂ α ∘ coit ((ρ ∘ now +₁ id) ∘ out)) ≈⟨ g-preserving ⟩ ((g +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ (ρ ∘ now +₁ id) ∘ out)) # ≈˘⟨ #-resp-≈ (∘-resp-≈ʳ (∘-resp-≈ʳ (⁂∘⁂ ○ ⁂-cong₂ identity² refl))) ⟩ ((g +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ (ρ ∘ now +₁ id)) ∘ (id ⁂ out)) # ≈⟨ #-resp-≈ (∘-resp-≈ʳ (extendʳ (sym (distributeˡ⁻¹-natural id (ρ ∘ now) id))) ○ pullˡ (+₁∘+₁ ○ +₁-cong₂ refl (elimʳ (⟨⟩-unique id-comm id-comm)))) ⟩ ((g ∘ (id ⁂ ρ ∘ now) +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ out)) # ≈˘⟨ #-resp-≈ (∘-resp-≈ˡ (+₁-cong₂ g-law refl)) ⟩ ((f +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ out)) # ≈⟨ #-Uniformity (sym (coit-commutes ((f +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ out)))) ⟩ out # ∘ coit ((f +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ out)) ≈˘⟨ (refl⟩∘⟨ (D₁-coit (distributeˡ⁻¹ ∘ (id ⁂ out)) f)) ⟩ a ∘ D₁ f ∘ coit (distributeˡ⁻¹ ∘ (id ⁂ out)) ≈⟨ refl⟩∘⟨ refl⟩∘⟨ coit-unique (distributeˡ⁻¹ ∘ (id ⁂ out)) τ τ-commutes ⟩ a ∘ D₁ f ∘ τ ∎)) where open Elgot-Algebra EA using (_#; #-resp-≈; #-Uniformity) open IsCoequalizer (coeq-productsʳ {X} {Y} (id {Y})) using () renaming (coequalize to prod-coequalize; universal to prod-universal; unique to prod-unique) open Search-Algebra (Elgot⇒Search DM EA) using (A) renaming (α to a) open Module (Elgot⇒D-Algebra DM EA) ♯-preserving' : ∀ {Y} {EA : Elgot-Algebra} (f : Y × X ⇒ Elgot-Algebra.A EA) {Z} (g : Z ⇒ Ď₀ X + Z) → [ EA , f ]♯' ∘ (id ⁂ Search-Algebra-on.α s-alg-on ∘ coit g) ≈ Elgot-Algebra._# EA (([ EA , f ]♯' +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ g)) ♯-preserving' {Y} {EA} f g = begin [ EA , f ]♯' ∘ (id ⁂ α ∘ coit g) ≈˘⟨ refl⟩∘⟨ (⁂∘⁂ ○ ⁂-cong₂ identity² refl) ⟩ [ EA , f ]♯' ∘ (id ⁂ α) ∘ (id ⁂ coit g) ≈⟨ extendʳ (id⁂Dρ-epi ([ EA , f ]♯' ∘ (id ⁂ α)) (a ∘ D₁ ([ EA , f ]♯') ∘ τ) epi-helper) ○ ∘-resp-≈ʳ assoc ⟩ a ∘ D₁ ([ EA , f ]♯') ∘ τ ∘ (id ⁂ coit g) ≈˘⟨ refl⟩∘⟨ coit-unique (([ EA , f ]♯' +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ g)) (D₁ ([ EA , f ]♯') ∘ τ ∘ (id ⁂ coit g)) unique-helper ⟩ out # ∘ coit (([ EA , f ]♯' +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ g)) ≈˘⟨ #-Uniformity (sym (coit-commutes (([ EA , f ]♯' +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ g)))) ⟩ (([ EA , f ]♯' +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ g)) # ∎ where open IsCoequalizer (coeq-productsʳ {X} {Y} (id {Y})) using () renaming (coequalize to prod-coequalize; universal to prod-universal) open Elgot-Algebra EA using (_#; #-Uniformity) open Search-Algebra (Elgot⇒Search DM EA) using (A; identity₁) renaming (α to a) open Module (Elgot⇒D-Algebra DM EA) using () renaming (commute to a-commute) id⁂Dρ-epi : ∀ {X Y} → Epi (id {X} ⁂ D₁ (ρ {Y})) id⁂Dρ-epi {X} {Y} {Z} f g eq = epi₁ f g (epi₂ (f ∘ (id ⁂ D₁ π₁)) (g ∘ (id ⁂ D₁ π₁)) (epi₃ ((f ∘ (id ⁂ D₁ π₁)) ∘ (id ⁂ τ)) ((g ∘ (id ⁂ D₁ π₁)) ∘ (id ⁂ τ)) (begin ((f ∘ (id ⁂ D₁ π₁)) ∘ (id ⁂ τ)) ∘ (id ⁂ (ρ ⁂ id)) ≈⟨ pullʳ (⁂∘⁂ ○ ⁂-cong₂ refl (∘-resp-≈ʳ (⁂-cong₂ refl (sym D.F.identity)) ○ τ-natural ρ id) ○ sym ⁂∘⁂) ⟩ (f ∘ (id ⁂ D₁ π₁)) ∘ (id ⁂ D₁ (ρ ⁂ id)) ∘ (id ⁂ τ) ≈⟨ pullʳ (extendʳ (⁂∘⁂ ○ ⁂-cong₂ refl (sym D.F.homomorphism ○ D.F.F-resp-≈ project₁ ○ D.F.homomorphism) ○ sym ⁂∘⁂)) ⟩ f ∘ (id ⁂ D₁ ρ) ∘ (id ⁂ D₁ π₁) ∘ (id ⁂ τ) ≈⟨ extendʳ eq ⟩ g ∘ (id ⁂ D₁ ρ) ∘ (id ⁂ D₁ π₁) ∘ (id ⁂ τ) ≈˘⟨ pullʳ (extendʳ (⁂∘⁂ ○ ⁂-cong₂ refl (sym D.F.homomorphism ○ D.F.F-resp-≈ project₁ ○ D.F.homomorphism) ○ sym ⁂∘⁂)) ⟩ (g ∘ (id ⁂ D₁ π₁)) ∘ (id ⁂ D₁ (ρ ⁂ id)) ∘ (id ⁂ τ) ≈˘⟨ pullʳ (⁂∘⁂ ○ ⁂-cong₂ refl (∘-resp-≈ʳ (⁂-cong₂ refl (sym D.F.identity)) ○ τ-natural ρ id) ○ sym ⁂∘⁂) ⟩ ((g ∘ (id ⁂ D₁ π₁)) ∘ (id ⁂ τ)) ∘ (id ⁂ (ρ ⁂ id)) ∎))) where open Terminal terminal using (⊤) open cond-2 (c-2 Y) using () renaming (s-alg-on to s-alg-on-Y) open Search-Algebra-on s-alg-on-Y using () renaming (α to y) s-alg-Y : Search-Algebra s-alg-Y = record { A = Ď₀ Y ; search-algebra-on = s-alg-on-Y } epi₁ : Epi (id {X} ⁂ D₁ ((π₁ {Ď₀ Y} {⊤}))) epi₁ = Iso⇒Epi ([ X ×- ]-resp-Iso ([ D.F ]-resp-Iso (_≅_.iso A×⊤≅A))) epi₂ : Epi (id {X} ⁂ τ {Ď₀ Y} {⊤}) epi₂ {G} h i eq' = begin h ≈˘⟨ elimʳ (⟨⟩-unique id-comm (id-comm ○ ∘-resp-≈ˡ (sym (Retract.is-retract (tau-retract ⊤ s-alg-Y))))) ⟩ h ∘ (id ⁂ τ ∘ ⟨ y ∘ D₁ π₁ , D₁ π₂ ⟩) ≈˘⟨ refl⟩∘⟨ (⁂∘⁂ ○ ⁂-cong₂ identity² refl) ⟩ h ∘ (id ⁂ τ) ∘ (id ⁂ ⟨ y ∘ D₁ π₁ , D₁ π₂ ⟩) ≈⟨ extendʳ eq' ⟩ i ∘ (id ⁂ τ) ∘ (id ⁂ ⟨ y ∘ D₁ π₁ , D₁ π₂ ⟩) ≈⟨ refl⟩∘⟨ (⁂∘⁂ ○ ⁂-cong₂ identity² refl) ⟩ i ∘ (id ⁂ τ ∘ ⟨ y ∘ D₁ π₁ , D₁ π₂ ⟩) ≈⟨ elimʳ (⟨⟩-unique id-comm (id-comm ○ ∘-resp-≈ˡ (sym (Retract.is-retract (tau-retract ⊤ s-alg-Y))))) ⟩ i ∎ epi₃ : Epi (id {X} ⁂ (ρ {Y} ⁂ id {D₀ ⊤})) epi₃ = IsCoequalizer⇒Epi coeq-productsᵐ unique-helper : out ∘ D₁ ([ EA , f ]♯') ∘ τ ∘ (id ⁂ coit g) ≈ (id +₁ D₁ ([ EA , f ]♯') ∘ τ ∘ (id ⁂ coit g)) ∘ ([ EA , f ]♯' +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ g) unique-helper = begin out ∘ D₁ ([ EA , f ]♯') ∘ τ ∘ (id ⁂ coit g) ≈⟨ extendʳ (D₁-commutes [ EA , f ]♯') ⟩ ([ EA , f ]♯' +₁ D₁ [ EA , f ]♯') ∘ out ∘ τ ∘ (id ⁂ coit g) ≈⟨ refl⟩∘⟨ (extendʳ τ-commutes ○ ∘-resp-≈ʳ assoc) ⟩ ([ EA , f ]♯' +₁ D₁ [ EA , f ]♯') ∘ (id +₁ τ) ∘ distributeˡ⁻¹ ∘ (id ⁂ out) ∘ (id ⁂ coit g) ≈⟨ refl⟩∘⟨ refl⟩∘⟨ refl⟩∘⟨ (⁂∘⁂ ○ ⁂-cong₂ refl (coit-commutes g) ○ sym ⁂∘⁂) ⟩ ([ EA , f ]♯' +₁ D₁ [ EA , f ]♯') ∘ (id +₁ τ) ∘ distributeˡ⁻¹ ∘ (id ⁂ (id +₁ coit g)) ∘ (id ⁂ g) ≈⟨ refl⟩∘⟨ refl⟩∘⟨ extendʳ (sym (distributeˡ⁻¹-natural id id (coit g))) ⟩ ([ EA , f ]♯' +₁ D₁ [ EA , f ]♯') ∘ (id +₁ τ) ∘ ((id ⁂ id) +₁ (id ⁂ coit g)) ∘ distributeˡ⁻¹ ∘ (id ⁂ g) ≈⟨ pullˡ (+₁∘+₁ ○ +₁-cong₂ identityʳ refl) ○ pullˡ (+₁∘+₁ ○ +₁-cong₂ (elimʳ (⟨⟩-unique id-comm id-comm)) assoc) ⟩ ([ EA , f ]♯' +₁ D₁ [ EA , f ]♯' ∘ τ ∘ (id ⁂ coit g)) ∘ distributeˡ⁻¹ ∘ (id ⁂ g) ≈˘⟨ pullˡ (+₁∘+₁ ○ +₁-cong₂ identityˡ identityʳ) ⟩ (id +₁ D₁ ([ EA , f ]♯') ∘ τ ∘ (id ⁂ coit g)) ∘ ([ EA , f ]♯' +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ g) ∎ epi-helper : ([ EA , f ]♯' ∘ (id ⁂ α)) ∘ (id ⁂ D₁ ρ) ≈ (a ∘ D₁ ([ EA , f ]♯') ∘ τ) ∘ (id ⁂ D₁ ρ) epi-helper = begin ([ EA , f ]♯' ∘ (id ⁂ α)) ∘ (id ⁂ D₁ ρ) ≈⟨ pullʳ (⁂∘⁂ ○ ⁂-cong₂ refl (sym ρ-algebra-morphism-2) ○ sym ⁂∘⁂) ⟩ [ EA , f ]♯' ∘ (id ⁂ ρ) ∘ (id ⁂ D.μ.η _) ≈⟨ (extendʳ (sym (prod-universal {eq = f-coequalize EA f}))) ○ ∘-resp-≈ʳ assoc ⟩ a ∘ D₁ f ∘ τ ∘ (id ⁂ D.μ.η _) ≈⟨ refl⟩∘⟨ refl⟩∘⟨ sym strength.μ-η-comm ⟩ a ∘ D₁ f ∘ D.μ.η _ ∘ D₁ τ ∘ τ ≈⟨ refl⟩∘⟨ (extendʳ (sym (D.μ.commute _))) ⟩ a ∘ D.μ.η _ ∘ D₁ (D₁ f) ∘ D₁ τ ∘ τ ≈⟨ extendʳ (sym a-commute) ⟩ a ∘ D₁ a ∘ D₁ (D₁ f) ∘ D₁ τ ∘ τ ≈⟨ refl⟩∘⟨ (sym-assoc ○ pullˡ (∘-resp-≈ˡ (sym D.F.homomorphism) ○ sym D.F.homomorphism ○ D.F.F-resp-≈ assoc)) ⟩ a ∘ D₁ (a ∘ D₁ f ∘ τ) ∘ τ ≈⟨ refl⟩∘⟨ ((D.F.F-resp-≈ (prod-universal {eq = f-coequalize EA f}) ○ D.F.homomorphism) ⟩∘⟨refl) ⟩ a ∘ (D₁ ([ EA , f ]♯') ∘ D₁ (id ⁂ ρ)) ∘ τ ≈⟨ (∘-resp-≈ʳ (pullʳ (sym (τ-natural id ρ))) ○ assoc²εβ) ⟩ (a ∘ D₁ ([ EA , f ]♯') ∘ τ) ∘ (id ⁂ D₁ ρ) ∎ *-h : ∀ {EA : Elgot-Algebra} (f : X ⇒ Elgot-Algebra.A EA) → Ď₀ X ⇒ Elgot-Algebra.A EA *-h {EA} f = [ EA , f ∘ π₂ ]♯' ∘ ⟨ ! , id ⟩ where open Terminal terminal using (!) *-preserves : ∀ {EA : Elgot-Algebra} (f : X ⇒ Elgot-Algebra.A EA) {Z} {h : Z ⇒ Ď₀ X + Z} → ([ EA , f ∘ π₂ ]♯' ∘ ⟨ Terminal.! terminal , id ⟩) ∘ α ∘ coit h ≈ Elgot-Algebra._# EA (([ EA , f ∘ π₂ ]♯' ∘ ⟨ Terminal.! terminal , id ⟩ +₁ id) ∘ h) *-preserves {EA} f {Z} {h} = begin ([ EA , f ∘ π₂ ]♯' ∘ ⟨ ! , id ⟩) ∘ α ∘ coit h ≈⟨ pullʳ (⟨⟩∘ ○ ⟨⟩-cong₂ (sym (!-unique (! ∘ α ∘ coit h))) identityˡ) ⟩ [ EA , f ∘ π₂ ]♯' ∘ ⟨ ! , α ∘ coit h ⟩ ≈˘⟨ refl⟩∘⟨ (⁂∘⟨⟩ ○ ⟨⟩-cong₂ identityˡ identityʳ) ⟩ [ EA , f ∘ π₂ ]♯' ∘ (id ⁂ α ∘ coit h) ∘ ⟨ ! , id ⟩ ≈⟨ pullˡ (♯-preserving' (f ∘ π₂) h) ⟩ (([ EA , f ∘ π₂ ]♯' +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ h)) # ∘ ⟨ ! , id ⟩ ≈˘⟨ #-Uniformity uni-helper ⟩ (([ EA , f ∘ π₂ ]♯' ∘ ⟨ ! , id ⟩ +₁ id) ∘ h) # ∎ where open Terminal terminal using (!; !-unique) open Elgot-Algebra EA using (_#; #-Uniformity) uni-helper : (id +₁ ⟨ ! , id ⟩) ∘ ([ EA , f ∘ π₂ ]♯' ∘ ⟨ ! , id ⟩ +₁ id) ∘ h ≈ (([ EA , f ∘ π₂ ]♯' +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ h)) ∘ ⟨ ! , id ⟩ uni-helper = begin (id +₁ ⟨ ! , id ⟩) ∘ ([ EA , f ∘ π₂ ]♯' ∘ ⟨ ! , id ⟩ +₁ id) ∘ h ≈⟨ pullˡ (+₁∘+₁ ○ +₁-cong₂ identityˡ identityʳ) ⟩ ([ EA , f ∘ π₂ ]♯' ∘ ⟨ ! , id ⟩ +₁ ⟨ ! , id ⟩) ∘ h ≈˘⟨ pullˡ (+₁∘+₁ ○ +₁-cong₂ refl identityˡ) ⟩ ([ EA , f ∘ π₂ ]♯' +₁ id) ∘ (⟨ ! , id ⟩ +₁ ⟨ ! , id ⟩) ∘ h ≈⟨ refl⟩∘⟨ distrib-helper ⟩ ([ EA , f ∘ π₂ ]♯' +₁ id) ∘ distributeˡ⁻¹ ∘ ⟨ ! , h ⟩ ≈˘⟨ pullʳ (pullʳ (⁂∘⟨⟩ ○ ⟨⟩-cong₂ identityˡ identityʳ)) ⟩ (([ EA , f ∘ π₂ ]♯' +₁ id) ∘ distributeˡ⁻¹ ∘ (id ⁂ h)) ∘ ⟨ ! , id ⟩ ∎ where distrib-helper : (⟨ ! , id ⟩ +₁ ⟨ ! , id ⟩) ∘ h ≈ distributeˡ⁻¹ ∘ ⟨ ! , h ⟩ distrib-helper = Iso⇒Mono (IsIso.iso isIsoˡ) ((⟨ ! , id ⟩ +₁ ⟨ ! , id ⟩) ∘ h) (distributeˡ⁻¹ ∘ ⟨ ! , h ⟩) (begin distributeˡ ∘ (⟨ ! , id ⟩ +₁ ⟨ ! , id ⟩) ∘ h ≈⟨ pullˡ ([]∘+₁ ○ []-cong₂ (⁂∘⟨⟩ ○ ⟨⟩-cong₂ identityˡ identityʳ) (⁂∘⟨⟩ ○ ⟨⟩-cong₂ identityˡ identityʳ)) ⟩ [ ⟨ ! , i₁ ⟩ , ⟨ ! , i₂ ⟩ ] ∘ h ≈⟨ []-unique (⟨⟩∘ ○ ⟨⟩-cong₂ (sym (!-unique (! ∘ i₁))) identityˡ) (⟨⟩∘ ○ ⟨⟩-cong₂ (sym (!-unique (! ∘ i₂))) identityˡ) ⟩∘⟨refl ⟩ ⟨ ! , id ⟩ ∘ h ≈⟨ ⟨⟩∘ ○ ⟨⟩-cong₂ (sym (!-unique (! ∘ h))) identityˡ ⟩ ⟨ ! , h ⟩ ≈˘⟨ cancelˡ (IsIso.isoʳ isIsoˡ) ⟩ distributeˡ ∘ distributeˡ⁻¹ ∘ ⟨ ! , h ⟩ ∎) *-lift' : ∀ {EA : Elgot-Algebra} (f : X ⇒ Elgot-Algebra.A EA) → *-h {EA} f ∘ ρ ∘ now ≈ f *-lift' {EA} f = begin ([ EA , f ∘ π₂ ]♯' ∘ ⟨ ! , id ⟩) ∘ ρ ∘ now ≈⟨ pullʳ (⟨⟩∘ ○ ⟨⟩-cong₂ (sym (!-unique (! ∘ ρ ∘ now))) identityˡ) ⟩ [ EA , f ∘ π₂ ]♯' ∘ ⟨ ! , ρ ∘ now ⟩ ≈˘⟨ refl⟩∘⟨ (⁂∘⟨⟩ ○ ⟨⟩-cong₂ identityˡ identityʳ) ⟩ [ EA , f ∘ π₂ ]♯' ∘ (id ⁂ ρ ∘ now) ∘ ⟨ ! , id ⟩ ≈˘⟨ extendʳ (♯-law' {⊤} {EA} (f ∘ π₂)) ⟩ f ∘ π₂ ∘ ⟨ ! , id ⟩ ≈⟨ elimʳ project₂ ⟩ f ∎ where open Terminal terminal using (⊤; !; !-unique) *-uniq' : ∀ {EA : Elgot-Algebra} (f : X ⇒ Elgot-Algebra.A EA) (g : Elgot-Algebra-Morphism (record { A = Ď₀ X ; algebra = elgot' (c-2 X) }) EA) → EA-h g ∘ ρ ∘ now ≈ f → EA-h g ≈ *-h {EA} f *-uniq' {EA} f g g-lift = ρ-epi (EA-h g) (*-h {EA} f) (begin EA-h g ∘ ρ ≈⟨ refl⟩∘⟨ ρ-law' ⟩ EA-h g ∘ α ∘ coit ((ρ ∘ now +₁ id) ∘ out) ≈⟨ EA-preserves g ⟩ ((EA-h g +₁ id) ∘ (ρ ∘ now +₁ id) ∘ out) # ≈⟨ #-resp-≈ (pullˡ (+₁∘+₁ ○ +₁-cong₂ refl identity²)) ⟩ ((EA-h g ∘ ρ ∘ now +₁ id) ∘ out) # ≈⟨ #-resp-≈ (∘-resp-≈ˡ (+₁-cong₂ g-lift refl)) ⟩ ((f +₁ id) ∘ out) # ≈˘⟨ #-resp-≈ (∘-resp-≈ˡ (+₁-cong₂ (*-lift' {EA} f) refl)) ⟩ ((*-h {EA} f ∘ ρ ∘ now +₁ id) ∘ out) # ≈˘⟨ #-resp-≈ (pullˡ (+₁∘+₁ ○ +₁-cong₂ refl identity²)) ⟩ ((*-h {EA} f +₁ id) ∘ (ρ ∘ now +₁ id) ∘ out) # ≈˘⟨ *-preserves {EA} f ⟩ *-h {EA} f ∘ α ∘ coit ((ρ ∘ now +₁ id) ∘ out) ≈˘⟨ refl⟩∘⟨ ρ-law' ⟩ *-h {EA} f ∘ ρ ∎) where open Elgot-Algebra EA open Terminal terminal using (!; !-unique) 2⇒3 : (∀ X → cond-2 X) → (∀ X → cond-3 X) 2⇒3 c-2 X .elgot = elgot' (c-2 X) 2⇒3 c-2 X .isFO = record { _* = λ {EA} f → record { h = *-h {EA} f ; preserves = λ {Z} {h} → *-preserves {EA} f {Z} {h} } ; *-lift = λ {EA} f → *-lift' {EA} f ; *-uniq = λ {EA} f g g-lift → *-uniq' {EA} f g g-lift } where open Stable X c-2 2⇒3 c-2 X .isStable = record { [_,_]♯ = [_,_]♯' ; ♯-law = λ {Y} {EA} f → ♯-law' {Y} {EA} f ; ♯-preserving = λ {Y} {EA} f {Z} g → ♯-preserving' {Y} {EA} f {Z} g ; ♯-unique = λ {Y} {EA} f g g-law g-preserving → ♯-unique' {Y} {EA} f g g-law (λ {Z} {h} → g-preserving {Z} h) } where open Stable X c-2 2⇒3 c-2 X .ρ-algebra-morphism = begin ρ ∘ D.μ.η X ≈⟨ ρ-algebra-morphism-2 ⟩ α ∘ D₁ ρ ≈˘⟨ ((elimʳ (coit-unique out id (id-comm ○ ∘-resp-≈ˡ (sym ([]-cong₂ identityʳ identityʳ ○ +-η))))) ⟩∘⟨refl) ⟩ (α ∘ coit out) ∘ D₁ ρ ∎ where open cond-2 (c-2 X) renaming (ρ-algebra-morphism to ρ-algebra-morphism-2) open Search-Algebra-on s-alg-on 2⇒3 c-2 X .ρ-law = ρ-law' where open Stable X c-2 using (ρ-law')