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

-- Traversals parametrised by a pointed coalgebra
module SOAS.Metatheory.Traversal {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.Metatheory.Algebra โ…€F
open import SOAS.Metatheory.Semantics โ…€F โ…€:Str ๐”› ๐•‹:Init

open Strength โ…€:Str

private
  variable
    ฮ“ ฮ” ฮ˜ ฮ  : Ctx
    ฮฑ ฮฒ : T
    ๐’ซ ๐’ฌ ๐’œ : Familyโ‚›


-- Parametrised interpretation into an internal hom
module Traversal (๐’ซแดฎ : Coalgโ‚š ๐’ซ)(๐‘Ž๐‘™๐‘” : โ…€ ๐’œ โ‡พฬฃ ๐’œ)
                 (ฯ† : ๐’ซ โ‡พฬฃ ๐’œ)(ฯ‡ : ๐”› โ‡พฬฃ ใ€– ๐’œ , ๐’œ ใ€—) where

  open Coalgโ‚š ๐’ซแดฎ

  -- Under the assumptions ๐’œ and ใ€– ๐’ซ , ๐’œ ใ€— are both meta-algebras
  ๐’œแตƒ : MetaAlg ๐’œ
  ๐’œแตƒ = record { ๐‘Ž๐‘™๐‘” = ๐‘Ž๐‘™๐‘” ; ๐‘ฃ๐‘Ž๐‘Ÿ = ฮป x โ†’ ฯ† (ฮท x) ; ๐‘š๐‘ฃ๐‘Ž๐‘Ÿ = ฯ‡ }

  Travแตƒ : MetaAlg ใ€– ๐’ซ , ๐’œ ใ€—
  Travแตƒ = record
    { ๐‘Ž๐‘™๐‘”  = ฮป t ฯƒ โ†’ ๐‘Ž๐‘™๐‘” (str ๐’ซแดฎ ๐’œ t ฯƒ)
    ; ๐‘ฃ๐‘Ž๐‘Ÿ  = ฮป x ฯƒ โ†’ ฯ† (ฯƒ x)
    ; ๐‘š๐‘ฃ๐‘Ž๐‘Ÿ = ฮป ๐”ช ฮต ฯƒ โ†’ ฯ‡ ๐”ช (ฮป ๐”ซ โ†’ ฮต ๐”ซ ฯƒ)
    }

  -- ใ€– ๐’ซ , ๐’œ ใ€— is also a pointed โ–ก-coalgebra
  Travแต‡ : Coalg ใ€– ๐’ซ , ๐’œ ใ€—
  Travแต‡ = record { r = ฮป h ฯ ฯƒ โ†’ h (ฯƒ โˆ˜ ฯ) ; counit = refl ; comult = refl }

  Travแดฎ : Coalgโ‚š ใ€– ๐’ซ , ๐’œ ใ€—
  Travแดฎ = record { แต‡ = Travแต‡ ; ฮท = ฮป x ฯƒ โ†’ ฯ† (ฯƒ x) ; rโˆ˜ฮท = refl }

  open Semantics Travแตƒ public renaming (๐•ค๐•–๐•ž to ๐•ฅ๐•ฃ๐•’๐•ง)

  -- Traversal-specific homomorphism properties that incorporate a substitution
  ๐•ฅโŸจ๐•งโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{x : โ„ ฮฑ ฮ“} โ†’ ๐•ฅ๐•ฃ๐•’๐•ง (๐•ง๐•’๐•ฃ x) ฯƒ โ‰ก ฯ† (ฯƒ x)
  ๐•ฅโŸจ๐•งโŸฉ {ฯƒ = ฯƒ} = cong (ฮป - โ†’ - ฯƒ) โŸจ๐•งโŸฉ

  ๐•ฅโŸจ๐•žโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{๐”ช : ๐”› ฮฑ ฮ }{ฮต : ฮ  ~[ ๐•‹ ]โ† ฮ“}
       โ†’ ๐•ฅ๐•ฃ๐•’๐•ง (๐•ž๐•ง๐•’๐•ฃ ๐”ช ฮต) ฯƒ โ‰ก ฯ‡ ๐”ช (ฮป p โ†’ ๐•ฅ๐•ฃ๐•’๐•ง (ฮต p) ฯƒ)
  ๐•ฅโŸจ๐•žโŸฉ {ฯƒ = ฯƒ} = cong (ฮป - โ†’ - ฯƒ) โŸจ๐•žโŸฉ

  ๐•ฅโŸจ๐•’โŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{t : โ…€ ๐•‹ ฮฑ ฮ“}
       โ†’ ๐•ฅ๐•ฃ๐•’๐•ง (๐•’๐•๐•˜ t) ฯƒ โ‰ก ๐‘Ž๐‘™๐‘” (str ๐’ซแดฎ ๐’œ (โ…€โ‚ ๐•ฅ๐•ฃ๐•’๐•ง t) ฯƒ)
  ๐•ฅโŸจ๐•’โŸฉ {ฯƒ = ฯƒ} = cong (ฮป - โ†’ - ฯƒ) โŸจ๐•’โŸฉ

  -- Congruence in the two arguments of ๐•ฅ๐•ฃ๐•’๐•ง
  ๐•ฅโ‰ˆโ‚ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{tโ‚ tโ‚‚ : ๐•‹ ฮฑ ฮ“} โ†’ tโ‚ โ‰ก tโ‚‚ โ†’ ๐•ฅ๐•ฃ๐•’๐•ง tโ‚ ฯƒ โ‰ก ๐•ฅ๐•ฃ๐•’๐•ง tโ‚‚ ฯƒ
  ๐•ฅโ‰ˆโ‚ {ฯƒ = ฯƒ} p = cong (ฮป - โ†’ ๐•ฅ๐•ฃ๐•’๐•ง - ฯƒ) p

  ๐•ฅโ‰ˆโ‚‚ : {ฯƒโ‚ ฯƒโ‚‚ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{t : ๐•‹ ฮฑ ฮ“}
      โ†’ ({ฯ„ : T}{x : โ„ ฯ„ ฮ“} โ†’ ฯƒโ‚ x โ‰ก ฯƒโ‚‚ x)
      โ†’ ๐•ฅ๐•ฃ๐•’๐•ง t ฯƒโ‚ โ‰ก ๐•ฅ๐•ฃ๐•’๐•ง t ฯƒโ‚‚
  ๐•ฅโ‰ˆโ‚‚ {t = t} p = cong (๐•ฅ๐•ฃ๐•’๐•ง t) (dextโ€ฒ p)


-- A pointed meta-ฮ›-algebra induces ๐•’๐•๐•˜ traversal into โ–ก ๐’œ
module โ–กTraversal {๐’œ} (๐’œแตƒ : MetaAlg ๐’œ) =
  Traversal โ„แดฎ (MetaAlg.๐‘Ž๐‘™๐‘” ๐’œแตƒ) (MetaAlg.๐‘ฃ๐‘Ž๐‘Ÿ ๐’œแตƒ) (MetaAlg.๐‘š๐‘ฃ๐‘Ž๐‘Ÿ ๐’œแตƒ)

-- Corollary: โ–ก lifts to an endofunctor on pointed meta-ฮ›-algebras
โ–กแตƒ : (๐’œแตƒ : MetaAlg ๐’œ) โ†’ MetaAlg (โ–ก ๐’œ)
โ–กแตƒ = โ–กTraversal.Travแตƒ

-- Helper records for proving equality of maps f, g out of ๐•‹,
-- with 0, 1 or 2 parameters
record MapEqโ‚€ (๐’œ : Familyโ‚›)(f g : ๐•‹ โ‡พฬฃ ๐’œ) : Set where
  field
    แตƒ : MetaAlg ๐’œ
  open Semantics แตƒ
  open ๐’œ

  field
    fโŸจ๐‘ฃโŸฉ : {x : โ„ ฮฑ ฮ“}
         โ†’ f (๐•ง๐•’๐•ฃ x) โ‰ก ๐‘ฃ๐‘Ž๐‘Ÿ x
    fโŸจ๐‘šโŸฉ : {๐”ช : ๐”› ฮฑ ฮ }{ฮต : ฮ  ~[ ๐•‹ ]โ† ฮ“}
         โ†’ f (๐•ž๐•ง๐•’๐•ฃ ๐”ช ฮต) โ‰ก ๐‘š๐‘ฃ๐‘Ž๐‘Ÿ ๐”ช (f โˆ˜ ฮต)
    fโŸจ๐‘ŽโŸฉ : {t : โ…€ ๐•‹ ฮฑ ฮ“}
         โ†’ f (๐•’๐•๐•˜ t) โ‰ก ๐‘Ž๐‘™๐‘” (โ…€โ‚ f t)
    gโŸจ๐‘ฃโŸฉ : {x : โ„ ฮฑ ฮ“}
         โ†’ g (๐•ง๐•’๐•ฃ x) โ‰ก ๐‘ฃ๐‘Ž๐‘Ÿ x
    gโŸจ๐‘šโŸฉ : {๐”ช : ๐”› ฮฑ ฮ }{ฮต : ฮ  ~[ ๐•‹ ]โ† ฮ“}
         โ†’ g (๐•ž๐•ง๐•’๐•ฃ ๐”ช ฮต) โ‰ก ๐‘š๐‘ฃ๐‘Ž๐‘Ÿ ๐”ช (g โˆ˜ ฮต)
    gโŸจ๐‘ŽโŸฉ : {t : โ…€ ๐•‹ ฮฑ ฮ“}
         โ†’ g (๐•’๐•๐•˜ t) โ‰ก ๐‘Ž๐‘™๐‘” (โ…€โ‚ g t)

  fแตƒ : MetaAlgโ‡’ ๐•‹แตƒ แตƒ f
  fแตƒ = record { โŸจ๐‘Ž๐‘™๐‘”โŸฉ =  fโŸจ๐‘ŽโŸฉ ; โŸจ๐‘ฃ๐‘Ž๐‘ŸโŸฉ =  fโŸจ๐‘ฃโŸฉ ; โŸจ๐‘š๐‘ฃ๐‘Ž๐‘ŸโŸฉ =  fโŸจ๐‘šโŸฉ }
  gแตƒ : MetaAlgโ‡’ ๐•‹แตƒ แตƒ g
  gแตƒ = record { โŸจ๐‘Ž๐‘™๐‘”โŸฉ =  gโŸจ๐‘ŽโŸฉ ; โŸจ๐‘ฃ๐‘Ž๐‘ŸโŸฉ =  gโŸจ๐‘ฃโŸฉ ; โŸจ๐‘š๐‘ฃ๐‘Ž๐‘ŸโŸฉ =  gโŸจ๐‘šโŸฉ }

  โ‰ˆ : (t : ๐•‹ ฮฑ ฮ“) โ†’ f t โ‰ก g t
  โ‰ˆ t = eq fแตƒ gแตƒ t

record MapEqโ‚ (๐’ซแดฎ : Coalgโ‚š ๐’ซ)(๐‘Ž๐‘™๐‘” : โ…€ ๐’œ โ‡พฬฃ ๐’œ)
              (f g : ๐•‹ โ‡พฬฃ ใ€– ๐’ซ , ๐’œ ใ€—) : Set where
  field
    ฯ† : ๐’ซ โ‡พฬฃ ๐’œ
    ฯ‡ : ๐”› โ‡พฬฃ ใ€– ๐’œ , ๐’œ ใ€—

  open Traversal ๐’ซแดฎ ๐‘Ž๐‘™๐‘” ฯ† ฯ‡

  field
    fโŸจ๐‘ฃโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{x : โ„ ฮฑ ฮ“}
         โ†’ f (๐•ง๐•’๐•ฃ x) ฯƒ โ‰ก ฯ† (ฯƒ x)
    fโŸจ๐‘šโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{๐”ช : ๐”› ฮฑ ฮ }{ฮต : ฮ  ~[ ๐•‹ ]โ† ฮ“}
         โ†’ f (๐•ž๐•ง๐•’๐•ฃ ๐”ช ฮต) ฯƒ โ‰ก ฯ‡ ๐”ช (ฮป p โ†’ f (ฮต p) ฯƒ)
    fโŸจ๐‘ŽโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{t : โ…€ ๐•‹ ฮฑ ฮ“}
         โ†’ f (๐•’๐•๐•˜ t) ฯƒ โ‰ก ๐‘Ž๐‘™๐‘” (str ๐’ซแดฎ ๐’œ (โ…€โ‚ f t) ฯƒ)
    gโŸจ๐‘ฃโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{x : โ„ ฮฑ ฮ“}
         โ†’ g (๐•ง๐•’๐•ฃ x) ฯƒ โ‰ก ฯ† (ฯƒ x)
    gโŸจ๐‘šโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{๐”ช : ๐”› ฮฑ ฮ }{ฮต : ฮ  ~[ ๐•‹ ]โ† ฮ“}
         โ†’ g (๐•ž๐•ง๐•’๐•ฃ ๐”ช ฮต) ฯƒ โ‰ก ฯ‡ ๐”ช (ฮป p โ†’ g (ฮต p) ฯƒ)
    gโŸจ๐‘ŽโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{t : โ…€ ๐•‹ ฮฑ ฮ“}
         โ†’ g (๐•’๐•๐•˜ t) ฯƒ โ‰ก ๐‘Ž๐‘™๐‘” (str ๐’ซแดฎ ๐’œ (โ…€โ‚ g t) ฯƒ)

  fแตƒ : MetaAlgโ‡’ ๐•‹แตƒ Travแตƒ f
  fแตƒ = record { โŸจ๐‘Ž๐‘™๐‘”โŸฉ = dextโ€ฒ fโŸจ๐‘ŽโŸฉ ; โŸจ๐‘ฃ๐‘Ž๐‘ŸโŸฉ = dextโ€ฒ fโŸจ๐‘ฃโŸฉ ; โŸจ๐‘š๐‘ฃ๐‘Ž๐‘ŸโŸฉ = dextโ€ฒ fโŸจ๐‘šโŸฉ }
  gแตƒ : MetaAlgโ‡’ ๐•‹แตƒ Travแตƒ g
  gแตƒ = record { โŸจ๐‘Ž๐‘™๐‘”โŸฉ = dextโ€ฒ gโŸจ๐‘ŽโŸฉ ; โŸจ๐‘ฃ๐‘Ž๐‘ŸโŸฉ = dextโ€ฒ gโŸจ๐‘ฃโŸฉ ; โŸจ๐‘š๐‘ฃ๐‘Ž๐‘ŸโŸฉ = dextโ€ฒ gโŸจ๐‘šโŸฉ }

  โ‰ˆ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}(t : ๐•‹ ฮฑ ฮ“) โ†’ f t ฯƒ โ‰ก g t ฯƒ
  โ‰ˆ {ฯƒ = ฯƒ} t = cong (ฮป - โ†’ - ฯƒ) (eq fแตƒ gแตƒ t)

record MapEqโ‚‚ (๐’ซแดฎ : Coalgโ‚š ๐’ซ)(๐’ฌแดฎ : Coalgโ‚š ๐’ฌ)(๐‘Ž๐‘™๐‘” : โ…€ ๐’œ โ‡พฬฃ ๐’œ)
                (f g : ๐•‹ โ‡พฬฃ ใ€– ๐’ซ , ใ€– ๐’ฌ , ๐’œ ใ€— ใ€—) : Set where
  field
    ฯ† : ๐’ฌ โ‡พฬฃ ๐’œ
    ฯ• : ๐’ซ โ‡พฬฃ ใ€– ๐’ฌ , ๐’œ ใ€—
    ฯ‡ : ๐”› โ‡พฬฃ ใ€– ๐’œ , ๐’œ ใ€—

  open Traversal ๐’ซแดฎ (Traversal.๐’œ.๐‘Ž๐‘™๐‘” ๐’ฌแดฎ ๐‘Ž๐‘™๐‘” ฯ† ฯ‡) ฯ• (ฮป ๐”ช ฮต ฯƒ โ†’ ฯ‡ ๐”ช (ฮป ๐”ซ โ†’ ฮต ๐”ซ ฯƒ))

  field
    fโŸจ๐‘ฃโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{ฯ‚ : ฮ” ~[ ๐’ฌ ]โ† ฮ˜}{x : โ„ ฮฑ ฮ“}
         โ†’ f (๐•ง๐•’๐•ฃ x) ฯƒ ฯ‚ โ‰ก ฯ• (ฯƒ x) ฯ‚
    fโŸจ๐‘šโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{ฯ‚ : ฮ” ~[ ๐’ฌ ]โ† ฮ˜}{๐”ช : ๐”› ฮฑ ฮ }{ฮต : ฮ  ~[ ๐•‹ ]โ† ฮ“}
         โ†’ f (๐•ž๐•ง๐•’๐•ฃ ๐”ช ฮต) ฯƒ ฯ‚ โ‰ก ฯ‡ ๐”ช (ฮป ๐”ซ โ†’ f (ฮต ๐”ซ) ฯƒ ฯ‚)
    fโŸจ๐‘ŽโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{ฯ‚ : ฮ” ~[ ๐’ฌ ]โ† ฮ˜}{t : โ…€ ๐•‹ ฮฑ ฮ“}
         โ†’ f (๐•’๐•๐•˜ t) ฯƒ ฯ‚ โ‰ก ๐‘Ž๐‘™๐‘” (str ๐’ฌแดฎ ๐’œ (str ๐’ซแดฎ ใ€– ๐’ฌ , ๐’œ ใ€— (โ…€โ‚ f t) ฯƒ) ฯ‚)
    gโŸจ๐‘ฃโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{ฯ‚ : ฮ” ~[ ๐’ฌ ]โ† ฮ˜}{x : โ„ ฮฑ ฮ“}
         โ†’ g (๐•ง๐•’๐•ฃ x) ฯƒ ฯ‚ โ‰ก ฯ• (ฯƒ x) ฯ‚
    gโŸจ๐‘šโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{ฯ‚ : ฮ” ~[ ๐’ฌ ]โ† ฮ˜}{๐”ช : ๐”› ฮฑ ฮ }{ฮต : ฮ  ~[ ๐•‹ ]โ† ฮ“}
         โ†’ g (๐•ž๐•ง๐•’๐•ฃ ๐”ช ฮต) ฯƒ ฯ‚ โ‰ก ฯ‡ ๐”ช (ฮป ๐”ซ โ†’ g (ฮต ๐”ซ) ฯƒ ฯ‚)
    gโŸจ๐‘ŽโŸฉ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{ฯ‚ : ฮ” ~[ ๐’ฌ ]โ† ฮ˜}{t : โ…€ ๐•‹ ฮฑ ฮ“}
         โ†’ g (๐•’๐•๐•˜ t) ฯƒ ฯ‚ โ‰ก ๐‘Ž๐‘™๐‘” (str ๐’ฌแดฎ ๐’œ (str ๐’ซแดฎ ใ€– ๐’ฌ , ๐’œ ใ€— (โ…€โ‚ g t) ฯƒ) ฯ‚)

  fแตƒ : MetaAlgโ‡’ ๐•‹แตƒ Travแตƒ f
  fแตƒ = record { โŸจ๐‘Ž๐‘™๐‘”โŸฉ = dextโ€ฒ (dextโ€ฒ fโŸจ๐‘ŽโŸฉ) ; โŸจ๐‘ฃ๐‘Ž๐‘ŸโŸฉ = dextโ€ฒ (dextโ€ฒ fโŸจ๐‘ฃโŸฉ)
              ; โŸจ๐‘š๐‘ฃ๐‘Ž๐‘ŸโŸฉ = dextโ€ฒ (dextโ€ฒ fโŸจ๐‘šโŸฉ) }
  gแตƒ : MetaAlgโ‡’ ๐•‹แตƒ Travแตƒ g
  gแตƒ = record { โŸจ๐‘Ž๐‘™๐‘”โŸฉ = dextโ€ฒ (dextโ€ฒ gโŸจ๐‘ŽโŸฉ) ; โŸจ๐‘ฃ๐‘Ž๐‘ŸโŸฉ = dextโ€ฒ (dextโ€ฒ gโŸจ๐‘ฃโŸฉ)
              ; โŸจ๐‘š๐‘ฃ๐‘Ž๐‘ŸโŸฉ = dextโ€ฒ (dextโ€ฒ gโŸจ๐‘šโŸฉ) }

  โ‰ˆ : {ฯƒ : ฮ“ ~[ ๐’ซ ]โ† ฮ”}{ฯ‚ : ฮ” ~[ ๐’ฌ ]โ† ฮ˜}(t : ๐•‹ ฮฑ ฮ“) โ†’ f t ฯƒ ฯ‚ โ‰ก g t ฯƒ ฯ‚
  โ‰ˆ {ฯƒ = ฯƒ}{ฯ‚} t = cong (ฮป - โ†’ - ฯƒ ฯ‚) (eq fแตƒ gแตƒ t)

-- Interaction of traversal and interpretation
module _ (๐’ซแดฎ : Coalgโ‚š ๐’ซ)(๐’œแตƒ : MetaAlg ๐’œ)(ฯ† : ๐’ซ โ‡พฬฃ ๐’œ) where
  open MetaAlg ๐’œแตƒ
  open Coalgโ‚š ๐’ซแดฎ
  open Semantics ๐’œแตƒ
  open Traversal ๐’ซแดฎ ๐‘Ž๐‘™๐‘” ฯ† ๐‘š๐‘ฃ๐‘Ž๐‘Ÿ using (๐•ฅ๐•ฃ๐•’๐•ง ; ๐•ฅโŸจ๐•’โŸฉ ; ๐•ฅโŸจ๐•งโŸฉ ; ๐•ฅโŸจ๐•žโŸฉ)
  open โ‰ก-Reasoning

  -- Traversal with the point of ๐’ซ is the same as direct interpretation
  ๐•ฅ๐•ฃ๐•’๐•ง-ฮทโ‰ˆ๐•ค๐•–๐•ž : (ฯ†โˆ˜ฮทโ‰ˆ๐‘ฃ๐‘Ž๐‘Ÿ : โˆ€{ฮฑ ฮ“}{v : โ„ ฮฑ ฮ“} โ†’ ฯ† (ฮท v) โ‰ก ๐‘ฃ๐‘Ž๐‘Ÿ v){t : ๐•‹ ฮฑ ฮ“}
        โ†’ ๐•ฅ๐•ฃ๐•’๐•ง t ฮท โ‰ก ๐•ค๐•–๐•ž t
  ๐•ฅ๐•ฃ๐•’๐•ง-ฮทโ‰ˆ๐•ค๐•–๐•ž ฯ†โˆ˜ฮทโ‰ˆ๐‘ฃ๐‘Ž๐‘Ÿ {t = t} = Semantics.eq ๐’œแตƒ (record
    { โŸจ๐‘Ž๐‘™๐‘”โŸฉ = ฮป{ {t = t} โ†’ trans ๐•ฅโŸจ๐•’โŸฉ (cong ๐‘Ž๐‘™๐‘” (begin
          str ๐’ซแดฎ ๐’œ (โ…€โ‚ ๐•ฅ๐•ฃ๐•’๐•ง t) ฮท
      โ‰กโŸจ str-natโ‚ (ฮทแดฎโ‡’ ๐’ซแดฎ) (โ…€โ‚ ๐•ฅ๐•ฃ๐•’๐•ง t) id โŸฉ
          str โ„แดฎ ๐’œ (โ…€โ‚ (ฮป{ h ฯ โ†’ h (ฮท โˆ˜ ฯ)}) ((โ…€โ‚ ๐•ฅ๐•ฃ๐•’๐•ง t))) id
      โ‰กโŸจ str-unit ๐’œ ((โ…€โ‚ (ฮป{ h ฯ โ†’ h (ฮท โˆ˜ ฯ)}) ((โ…€โ‚ ๐•ฅ๐•ฃ๐•’๐•ง t)))) โŸฉ
          โ…€โ‚ (i ๐’œ) (โ…€โ‚ (ฮป { h ฯ โ†’ h (ฮท โˆ˜ ฯ) }) (โ…€โ‚ ๐•ฅ๐•ฃ๐•’๐•ง t))
      โ‰กห˜โŸจ trans โ…€.homomorphism โ…€.homomorphism โŸฉ
          โ…€โ‚ (ฮป t โ†’ ๐•ฅ๐•ฃ๐•’๐•ง t ฮท) t
      โˆŽ))}
    ; โŸจ๐‘ฃ๐‘Ž๐‘ŸโŸฉ = ฮป{ {v = v} โ†’ trans ๐•ฅโŸจ๐•งโŸฉ ฯ†โˆ˜ฮทโ‰ˆ๐‘ฃ๐‘Ž๐‘Ÿ }
    ; โŸจ๐‘š๐‘ฃ๐‘Ž๐‘ŸโŸฉ = ฮป{ {๐”ช}{ฮต} โ†’ ๐•ฅโŸจ๐•žโŸฉ } }) ๐•ค๐•–๐•žแตƒโ‡’ t

-- Traversal with the point of ๐’ซ into ๐•‹  is the identity
๐•ฅ๐•ฃ๐•’๐•ง-ฮทโ‰ˆid : (๐’ซแดฎ : Coalgโ‚š ๐’ซ)(open Coalgโ‚š ๐’ซแดฎ)(ฯ† : ๐’ซ โ‡พฬฃ ๐•‹)
          (ฯ†โˆ˜ฮทโ‰ˆ๐‘ฃ๐‘Ž๐‘Ÿ : โˆ€{ฮฑ ฮ“}{v : โ„ ฮฑ ฮ“} โ†’ ฯ† (ฮท v) โ‰ก ๐•ง๐•’๐•ฃ v){t : ๐•‹ ฮฑ ฮ“}
         โ†’ Traversal.๐•ฅ๐•ฃ๐•’๐•ง ๐’ซแดฎ ๐•’๐•๐•˜ ฯ† ๐•ž๐•ง๐•’๐•ฃ t ฮท โ‰ก t
๐•ฅ๐•ฃ๐•’๐•ง-ฮทโ‰ˆid ๐’ซแดฎ ฯ† ฯ†โˆ˜ฮทโ‰ˆ๐‘ฃ๐‘Ž๐‘Ÿ = trans (๐•ฅ๐•ฃ๐•’๐•ง-ฮทโ‰ˆ๐•ค๐•–๐•ž ๐’ซแดฎ ๐•‹แตƒ ฯ† ฯ†โˆ˜ฮทโ‰ˆ๐‘ฃ๐‘Ž๐‘Ÿ) ๐•ค๐•–๐•ž-id

-- Corollaries for โ„-parametrised traversals
โ–ก๐•ฅ๐•ฃ๐•’๐•ง-idโ‰ˆ๐•ค๐•–๐•ž : (๐’œแตƒ : MetaAlgย ๐’œ){t : ๐•‹ ฮฑ ฮ“}
            โ†’ โ–กTraversal.๐•ฅ๐•ฃ๐•’๐•ง ๐’œแตƒ t id โ‰ก Semantics.๐•ค๐•–๐•ž ๐’œแตƒ t
โ–ก๐•ฅ๐•ฃ๐•’๐•ง-idโ‰ˆ๐•ค๐•–๐•ž ๐’œแตƒ {t} = ๐•ฅ๐•ฃ๐•’๐•ง-ฮทโ‰ˆ๐•ค๐•–๐•ž โ„แดฎ ๐’œแตƒ (MetaAlg.๐‘ฃ๐‘Ž๐‘Ÿ ๐’œแตƒ) refl

โ–ก๐•ฅ๐•ฃ๐•’๐•ง-idโ‰ˆid : {t : ๐•‹ ฮฑ ฮ“} โ†’ โ–กTraversal.๐•ฅ๐•ฃ๐•’๐•ง ๐•‹แตƒ t id โ‰ก t
โ–ก๐•ฅ๐•ฃ๐•’๐•ง-idโ‰ˆid = ๐•ฅ๐•ฃ๐•’๐•ง-ฮทโ‰ˆid โ„แดฎ ๐•ง๐•’๐•ฃ refl