\begin{code} {-# OPTIONS --safe #-} open import Prelude open import Algebra open import Path.Reasoning module Codata.CIM where private variable X : Type module _ (M M̅ : Type → Type) (mon : Monad M) (fnc : Functor M̅) where open Monad mon open Functor fnc μ : M (M A) → M A μ xs = xs >>= id η = return M[_] : (A → B) → M A → M B M[_] = mmap M̅[_] : (A → B) → M̅ A → M̅ B M̅[_] = map μ∘η : μ ∘ η {A = M A} ≡ id μ∘η = funExt (>>=-idˡ _) η∘Mμ : μ ∘ M[ η {A = A} ] ≡ id η∘Mμ = funExt λ x → >>=-assoc x _ _ ; cong (x >>=_) (funExt λ x′ → >>=-idˡ _ (η x′)) ; >>=-idʳ x η∘f : (f : A → B) → η ∘ f ≡ M[ f ] ∘ η η∘f f = funExt λ x → sym (>>=-idˡ _ _) f∘μ : (f : A → B) → μ ∘ M[ M[ f ] ] ≡ M[ f ] ∘ μ f∘μ f = funExt λ x → >>=-assoc x _ _ ; cong (x >>=_) (funExt (λ x′ → >>=-idˡ _ _)) ; sym (>>=-assoc x _ _) μ-assoc : μ ∘ μ ≡ μ ∘ M[ μ { A = A } ] μ-assoc = funExt λ x → >>=-assoc x _ _ ; cong (x >>=_) (funExt λ x′ → sym (>>=-idˡ _ _)) ; sym (>>=-assoc x _ _) M[]-comp : (f : B → C) (g : A → B) → M[ f ] ∘ M[ g ] ≡ M[ f ∘ g ] M[]-comp f g = funExt (mmap-comp f g) μ-M : (f : A → M (M B)) → μ ∘ μ ∘ M[ f ] ≡ μ ∘ M[ μ ∘ f ] μ-M f = μ ∘ μ ∘ M[ f ] ≡⟨ cong (_∘ M[ f ]) μ-assoc ⟩ μ ∘ M[ μ ] ∘ M[ f ] ≡⟨ cong (μ ∘_) (M[]-comp μ f) ⟩ μ ∘ M[ μ ∘ f ] ∎ record Module : Type₁ where field μ′ : M̅ (M A) → M̅ A μ-η : μ′ ∘ M̅[ η ] ≡ id {A = M̅ A} μ-μ : μ′ ∘ μ′ {A = M A} ≡ μ′ ∘ M̅[ μ ] record Ideal : Type₁ where field mod : Module open Module mod public field σ : M̅ A → M A hom : μ ∘ σ ≡ σ ∘ μ′ {A = A} natural : (f : A → B) → σ ∘ M̅[ f ] ≡ M[ f ] ∘ σ Equation : Type → Type → Type \end{code} %<*equation> \begin{code} Equation X A = X → M (X ⊎ A) \end{code} %</equation> \begin{code} Solution : Type → Type → Type \end{code} %<*soln> \begin{code} Solution X A = X → M A \end{code} %</soln> \begin{code} infix 4 _Solves_ \end{code} %<*solves> \begin{code} _Solves_ : Solution X A → Equation X A → Type e† Solves e = e† ≡ μ ∘ M[ e† ▿ η ] ∘ e \end{code} %</solves> \begin{code} Flat : Type → Type → Type \end{code} %<*flat> \begin{code} Flat X A = X → M̅ (X ⊎ A) ⊎ A \end{code} %</flat> \begin{code} record CIM : Type₁ where field ideal : Ideal open Ideal ideal public infixl 30 _‡ field \end{code} %<*solve> \begin{code} _‡ : Flat X A → Solution X A \end{code} %</solve> %<*solution> \begin{code} solution : (eᵢ : Flat X A) → eᵢ ‡ Solves (σ ▿ η ∘ inr) ∘ eᵢ \end{code} %</solution> \begin{code} Flatᵍ : Type → Type → Type Flatᵍ X A = X → M (M̅ X ⊎ A) module _ (eⱼ : Flatᵍ X A) where e : Equation X A e = μ ∘ M[ M[ inl ] ∘ σ ▿ η ∘ inr ] ∘ eⱼ ẽᵢ : Flat (M̅ X) A ẽᵢ = inl ∘ μ′ ∘ M̅[ eⱼ ] ẽ : Equation (M̅ X) A ẽ = (σ ▿ η ∘ inr) ∘ ẽᵢ _ : ẽ ≡ σ ∘ μ′ ∘ M̅[ eⱼ ] _ = refl ẽ† : Solution (M̅ X) A ẽ† = ẽᵢ ‡ e† : Solution X A e† = μ ∘ M[ ẽ† ▿ η ] ∘ eⱼ lemma : μ ∘ M[ ẽ† ▿ η ] ∘ ẽ ≡ μ ∘ M[ e† ] ∘ σ lemma = μ ∘ M[ ẽ† ▿ η ] ∘ ẽ ≡⟨⟩ μ ∘ M[ ẽ† ▿ η ] ∘ σ ∘ μ′ ∘ M̅[ eⱼ ] ≡˘⟨ cong (λ s → μ ∘ M[ ẽ† ▿ η ] ∘ s ∘ M̅[ eⱼ ]) hom ⟩ μ ∘ M[ ẽ† ▿ η ] ∘ μ ∘ σ ∘ M̅[ eⱼ ] ≡⟨ cong (λ s → μ ∘ M[ ẽ† ▿ η ] ∘ μ ∘ s) (natural eⱼ) ⟩ μ ∘ M[ ẽ† ▿ η ] ∘ μ ∘ M[ eⱼ ] ∘ σ ≡˘⟨ cong (λ s → μ ∘ s ∘ M[ eⱼ ] ∘ σ) (f∘μ (ẽ† ▿ η) ) ⟩ μ ∘ μ ∘ M[ M[ ẽ† ▿ η ] ] ∘ M[ eⱼ ] ∘ σ ≡⟨ cong (λ s → μ ∘ μ ∘ s ∘ σ) (M[]-comp M[ ẽ† ▿ η ] eⱼ) ⟩ μ ∘ μ ∘ M[ M[ ẽ† ▿ η ] ∘ eⱼ ] ∘ σ ≡⟨ cong (_∘ σ) (μ-M _) ⟩ μ ∘ M[ μ ∘ M[ ẽ† ▿ η ] ∘ eⱼ ] ∘ σ ≡⟨⟩ μ ∘ M[ e† ] ∘ σ ∎ soln : e† Solves e soln = e† ≡⟨⟩ μ ∘ M[ ẽ† ▿ η ] ∘ eⱼ ≡⟨ cong (λ s → μ ∘ M[ s ▿ η ] ∘ eⱼ) (solution ẽᵢ) ⟩ μ ∘ M[ μ ∘ M[ ẽ† ▿ η ] ∘ ẽ ▿ η ] ∘ eⱼ ≡⟨ cong (λ s → μ ∘ M[ s ▿ η ] ∘ eⱼ) lemma ⟩ μ ∘ M[ μ ∘ M[ e† ] ∘ σ ▿ η ] ∘ eⱼ ≡˘⟨ cong (λ s → μ ∘ M[ μ ∘ M[ e† ] ∘ σ ▿ s ∘ η ] ∘ eⱼ ) μ∘η ⟩ μ ∘ M[ μ ∘ M[ e† ] ∘ σ ▿ μ ∘ η ∘ η ] ∘ eⱼ ≡⟨ cong (λ s → μ ∘ M[ s ] ∘ eⱼ) (funExt (▿-fusion μ _ _)) ⟩ μ ∘ M[ μ ∘ (M[ e† ] ∘ σ ▿ η ∘ η) ] ∘ eⱼ ≡˘⟨ cong (_∘ eⱼ) (μ-M (M[ e† ] ∘ σ ▿ η ∘ η)) ⟩ μ ∘ μ ∘ M[ M[ e† ] ∘ σ ▿ η ∘ η ] ∘ eⱼ ≡⟨⟩ μ ∘ μ ∘ M[ M[ (e† ▿ η) ∘ inl ] ∘ σ ▿ η ∘ η ] ∘ eⱼ ≡˘⟨ cong (λ s → μ ∘ μ ∘ M[ s ∘ σ ▿ η ∘ η ] ∘ eⱼ) (M[]-comp (e† ▿ η) inl) ⟩ μ ∘ μ ∘ M[ M[ e† ▿ η ] ∘ M[ inl ] ∘ σ ▿ η ∘ η ] ∘ eⱼ ≡⟨⟩ μ ∘ μ ∘ M[ M[ e† ▿ η ] ∘ M[ inl ] ∘ σ ▿ η ∘ (e† ▿ η) ∘ inr ] ∘ eⱼ ≡⟨ cong (λ s → μ ∘ μ ∘ M[ M[ e† ▿ η ] ∘ M[ inl ] ∘ σ ▿ s ∘ inr ] ∘ eⱼ) (η∘f (e† ▿ η)) ⟩ μ ∘ μ ∘ M[ M[ e† ▿ η ] ∘ M[ inl ] ∘ σ ▿ M[ e† ▿ η ] ∘ η ∘ inr ] ∘ eⱼ ≡⟨ cong (λ s → μ ∘ μ ∘ M[ s ] ∘ eⱼ) (funExt (▿-fusion M[ e† ▿ η ] _ _)) ⟩ μ ∘ μ ∘ M[ M[ e† ▿ η ] ∘ (M[ inl ] ∘ σ ▿ η ∘ inr) ] ∘ eⱼ ≡˘⟨ cong (λ s → μ ∘ μ ∘ s ∘ eⱼ) (M[]-comp M[ e† ▿ η ] (M[ inl ] ∘ σ ▿ η ∘ inr)) ⟩ μ ∘ μ ∘ M[ M[ e† ▿ η ] ] ∘ M[ M[ inl ] ∘ σ ▿ η ∘ inr ] ∘ eⱼ ≡⟨ cong (λ s → μ ∘ s ∘ M[ M[ inl ] ∘ σ ▿ η ∘ inr ] ∘ eⱼ) (f∘μ (e† ▿ η)) ⟩ μ ∘ M[ e† ▿ η ] ∘ μ ∘ M[ M[ inl ] ∘ σ ▿ η ∘ inr ] ∘ eⱼ ≡⟨⟩ μ ∘ M[ e† ▿ η ] ∘ e ∎ \end{code}