open import SOAS.Common
open import SOAS.Families.Core
open import Categories.Object.Initial
open import SOAS.Coalgebraic.Strength
import SOAS.Metatheory.MetaAlgebra

-- Renaming structure by initiality
module SOAS.Metatheory.Renaming {T : Set}
  (โ…€F : Functor ๐”ฝamiliesโ‚› ๐”ฝamiliesโ‚›) (โ…€:Str : Strength โ…€F)
  (๐”› : Familyโ‚›) (open SOAS.Metatheory.MetaAlgebra โ…€F ๐”›)
  (๐•‹:Init : Initial ๐•„etaAlgebras)
  where

open import SOAS.Context
open import SOAS.Variable
open import SOAS.Abstract.Hom
import SOAS.Abstract.Coalgebra as โ†’โ–ก ; open โ†’โ–ก.Sorted
import SOAS.Abstract.Box as โ–ก ; open โ–ก.Sorted

open import SOAS.Coalgebraic.Map

open import SOAS.Metatheory.Algebra {T} โ…€F
open import SOAS.Metatheory.Semantics โ…€F โ…€:Str ๐”› ๐•‹:Init
open import SOAS.Metatheory.Traversal โ…€F โ…€:Str ๐”› ๐•‹:Init

open Strength โ…€:Str

-- Renaming is a โ„-parametrised traversal into ๐•‹
module Renaming = โ–กTraversal ๐•‹แตƒ

๐•ฃ๐•–๐•Ÿ : ๐•‹ โ‡พฬฃ โ–ก ๐•‹
๐•ฃ๐•–๐•Ÿ = Renaming.๐•ฅ๐•ฃ๐•’๐•ง

๐•จ๐•œ : {ฮฑ ฯ„ : T}{ฮ“ : Ctx} โ†’ ๐•‹ ฮฑ ฮ“ โ†’ ๐•‹ ฮฑ (ฯ„ โˆ™ ฮ“)
๐•จ๐•œ t = ๐•ฃ๐•–๐•Ÿ t old

-- Comultiplication law
๐•ฃ๐•–๐•Ÿ-comp : MapEqโ‚‚ โ„แดฎ โ„แดฎ ๐•’๐•๐•˜ (ฮป t ฯ ฯฑ โ†’ ๐•ฃ๐•–๐•Ÿ t (ฯฑ โˆ˜ ฯ))
                           (ฮป t ฯ ฯฑ โ†’ ๐•ฃ๐•–๐•Ÿ (๐•ฃ๐•–๐•Ÿ t ฯ) ฯฑ)
๐•ฃ๐•–๐•Ÿ-comp = record
  { ฯ† = ๐•ง๐•’๐•ฃ
  ; ฯ• = ฮป x ฯ โ†’ ๐•ง๐•’๐•ฃ (ฯ x)
  ; ฯ‡ = ๐•ž๐•ง๐•’๐•ฃ
  ; fโŸจ๐‘ฃโŸฉ = ๐•ฅโŸจ๐•งโŸฉ
  ; fโŸจ๐‘šโŸฉ = ๐•ฅโŸจ๐•žโŸฉ
  ; fโŸจ๐‘ŽโŸฉ = ฮป{ {ฯƒ = ฯ}{ฯฑ}{t} โ†’ begin
        ๐•ฃ๐•–๐•Ÿ (๐•’๐•๐•˜ t) (ฯฑ โˆ˜ ฯ)
    โ‰กโŸจ ๐•ฅโŸจ๐•’โŸฉ โŸฉ
        ๐•’๐•๐•˜ (str โ„แดฎ ๐•‹ (โ…€โ‚ ๐•ฃ๐•–๐•Ÿ t) (ฯฑ โˆ˜ ฯ))
    โ‰กโŸจ cong ๐•’๐•๐•˜ (str-dist ๐•‹ (jแถœ โ„แดฎ) (โ…€โ‚ ๐•ฃ๐•–๐•Ÿ t) ฯ ฯฑ) โŸฉ
        ๐•’๐•๐•˜ (str โ„แดฎ ๐•‹ (str โ„แดฎ (โ–ก ๐•‹) (โ…€โ‚ (precomp ๐•‹ (j โ„)) (โ…€โ‚ ๐•ฃ๐•–๐•Ÿ t)) ฯ) ฯฑ)
    โ‰กห˜โŸจ congr โ…€.homomorphism (ฮป - โ†’ ๐•’๐•๐•˜ (str โ„แดฎ ๐•‹ (str โ„แดฎ (โ–ก ๐•‹) - ฯ) ฯฑ)) โŸฉ
        ๐•’๐•๐•˜ (str โ„แดฎ ๐•‹ (str โ„แดฎ (โ–ก ๐•‹) (โ…€โ‚ (ฮป{ t ฯ ฯฑ โ†’ ๐•ฃ๐•–๐•Ÿ t (ฯฑ โˆ˜ ฯ)}) t) ฯ) ฯฑ)
    โˆŽ }
  ; gโŸจ๐‘ฃโŸฉ = trans (๐•ฅโ‰ˆโ‚ ๐•ฅโŸจ๐•งโŸฉ) ๐•ฅโŸจ๐•งโŸฉ
  ; gโŸจ๐‘šโŸฉ = trans (๐•ฅโ‰ˆโ‚ ๐•ฅโŸจ๐•žโŸฉ) ๐•ฅโŸจ๐•žโŸฉ
  ; gโŸจ๐‘ŽโŸฉ = ฮป{ {ฯƒ = ฯ}{ฯฑ}{t} โ†’ begin
        ๐•ฃ๐•–๐•Ÿ (๐•ฃ๐•–๐•Ÿ (๐•’๐•๐•˜ t) ฯ) ฯฑ
    โ‰กโŸจ ๐•ฅโ‰ˆโ‚ ๐•ฅโŸจ๐•’โŸฉ โŸฉ
        ๐•ฃ๐•–๐•Ÿ (๐•’๐•๐•˜ (str โ„แดฎ ๐•‹ (โ…€โ‚ ๐•ฃ๐•–๐•Ÿ t) ฯ)) ฯฑ
    โ‰กโŸจ ๐•ฅโŸจ๐•’โŸฉ โŸฉ
        ๐•’๐•๐•˜ (str โ„แดฎ ๐•‹ (โ…€โ‚ ๐•ฃ๐•–๐•Ÿ (str โ„แดฎ ๐•‹ (โ…€โ‚ ๐•ฃ๐•–๐•Ÿ t) ฯ)) ฯฑ)
    โ‰กห˜โŸจ congr (str-natโ‚‚ ๐•ฃ๐•–๐•Ÿ (โ…€โ‚ ๐•ฃ๐•–๐•Ÿ t) ฯ) (ฮป - โ†’ ๐•’๐•๐•˜ (str โ„แดฎ ๐•‹ - ฯฑ)) โŸฉ
        ๐•’๐•๐•˜ (str โ„แดฎ ๐•‹ (str โ„แดฎ (โ–ก ๐•‹) (โ…€.Fโ‚ (ฮป { hโ€ฒ ฯ‚ โ†’ ๐•ฃ๐•–๐•Ÿ (hโ€ฒ ฯ‚) }) (โ…€โ‚ ๐•ฃ๐•–๐•Ÿ t)) ฯ) ฯฑ)
    โ‰กห˜โŸจ congr โ…€.homomorphism (ฮป - โ†’ ๐•’๐•๐•˜ (str โ„แดฎ ๐•‹ (str โ„แดฎ (โ–ก ๐•‹) - ฯ) ฯฑ)) โŸฉ
        ๐•’๐•๐•˜ (str โ„แดฎ ๐•‹ (str โ„แดฎ (โ–ก ๐•‹) (โ…€โ‚ (ฮป{ t ฯ ฯฑ โ†’ ๐•ฃ๐•–๐•Ÿ (๐•ฃ๐•–๐•Ÿ t ฯ) ฯฑ}) t) ฯ) ฯฑ)
    โˆŽ }
  }
  where
  open โ‰ก-Reasoning
  open Renaming


-- Pointed โ–ก-coalgebra structure for ๐•‹
๐•‹แต‡ : Coalg ๐•‹
๐•‹แต‡ = record { r = ๐•ฃ๐•–๐•Ÿ ; counit = โ–ก๐•ฅ๐•ฃ๐•’๐•ง-idโ‰ˆid
            ; comult = ฮป{ {t = t} โ†’ MapEqโ‚‚.โ‰ˆ ๐•ฃ๐•–๐•Ÿ-comp t } }

๐•‹แดฎ : Coalgโ‚š ๐•‹
๐•‹แดฎ = record { แต‡ = ๐•‹แต‡ ; ฮท = ๐•ง๐•’๐•ฃ ; rโˆ˜ฮท = Renaming.๐•ฅโŸจ๐•งโŸฉ }