open import Categories.Category.Core
open import Categories.Functor using (Endofunctor; Functor)
open import Categories.Object.Initial using (Initial)
open import Categories.Category.Construction.F-Algebras
open import Categories.Functor.Algebra using (F-Algebra; F-Algebra-Morphism)
import Categories.Morphism.Reasoning as MR
module Functor.Algebra.Recursion {o ℓ e} {C : Category o ℓ e} {F : Endofunctor C} (initial : Initial (F-Algebras F)) where
open Category C
open Initial initial
open F-Algebra ⊥ using () renaming (A to μF; α to inF)
private
module F = Functor F
open HomReasoning
open Equiv
open MR C
open F using (F₀; F₁)
abstract
⦅_⦆ : ∀ {X} → (F₀ X ⇒ X) → (μF ⇒ X)
⦅_⦆ {X} φ = F-Algebra-Morphism.f (! {record { A = X ; α = φ }})
cata-cancel : ∀ {X} {φ : F₀ X ⇒ X} → ⦅ φ ⦆ ∘ inF ≈ φ ∘ F₁ ⦅ φ ⦆
cata-cancel {X} {φ} = F-Algebra-Morphism.commutes !
cata-unique : ∀ {X} {φ : F₀ X ⇒ X} {f : μF ⇒ X} → f ∘ inF ≈ φ ∘ F₁ f → ⦅ φ ⦆ ≈ f
cata-unique {X} {φ} {f} f-cancel = !-unique (record { f = f ; commutes = f-cancel })
cata-refl : ⦅ inF ⦆ ≈ id {μF}
cata-refl = cata-unique (id-comm-sym ○ ∘-resp-≈ʳ (sym F.identity))
cata-fusion : ∀ {X Y} {φ : F₀ X ⇒ X} {ψ : F₀ Y ⇒ Y} {f : X ⇒ Y} → f ∘ φ ≈ ψ ∘ F₁ f → ⦅ ψ ⦆ ≈ f ∘ ⦅ φ ⦆
cata-fusion {X} {Y} {φ} {ψ} {f} eq = cata-unique (begin
(f ∘ ⦅ φ ⦆) ∘ inF ≈⟨ pullʳ cata-cancel ⟩
f ∘ φ ∘ F₁ ⦅ φ ⦆ ≈⟨ extendʳ eq ⟩
ψ ∘ F₁ f ∘ F₁ ⦅ φ ⦆ ≈˘⟨ refl⟩∘⟨ F.homomorphism ⟩
ψ ∘ F₁ (f ∘ ⦅ φ ⦆) ∎)