open import SOAS.Common
open import SOAS.Families.Core
import SOAS.Metatheory.MetaAlgebra

-- Shorthands for de Bruijn indices
module SOAS.Syntax.Shorthands {T : Set}
  {β…€F : Functor 𝔽amiliesβ‚› 𝔽amiliesβ‚›}
  (open SOAS.Metatheory.MetaAlgebra β…€F)
  {π’œ : Familyβ‚› β†’ Familyβ‚›}(π’œα΅ƒ : (𝔛 : Familyβ‚›) β†’ MetaAlg 𝔛 (π’œ 𝔛))
  where

open import SOAS.Context
open import SOAS.Families.Build
open import SOAS.ContextMaps.Inductive
open import SOAS.Variable
open import Data.Nat
open import Data.Empty

private
  variable
    Ξ± Ξ² Ξ³ Ξ΄ Ο… : T
    Ξ“ Ξ” : Ctx

module _ {𝔛 : Familyβ‚›} where
  open MetaAlg 𝔛 (π’œα΅ƒ 𝔛)

  ix : Ctx β†’ β„• β†’ T
  ix βˆ… n = βŠ₯-elim impossible where postulate impossible : βŠ₯
  ix (Ξ± βˆ™ Ξ“) 0 = Ξ±
  ix (Ξ± βˆ™ Ξ“) (suc n) = ix Ξ“ n

  deBruijn : (n : β„•) β†’ ℐ (ix Ξ“ n) Ξ“
  deBruijn {Ξ± βˆ™ Ξ“} 0 = new
  deBruijn {Ξ± βˆ™ Ξ“} (suc n) = old (deBruijn n)
  deBruijn {βˆ…}     _       = βŠ₯-elim impossible where postulate impossible : βŠ₯

  β€² : {Ξ“ : Ctx}(n : β„•) β†’ π’œ 𝔛 (ix Ξ“ n) Ξ“
  β€² n = π‘£π‘Žπ‘Ÿ (deBruijn n)

  xβ‚€ : π’œ 𝔛 Ξ± (Ξ± βˆ™ Ξ“)
  xβ‚€ = π‘£π‘Žπ‘Ÿ new
  x₁ : π’œ 𝔛 Ξ² (Ξ± βˆ™ Ξ² βˆ™ Ξ“)
  x₁ = π‘£π‘Žπ‘Ÿ (old new)
  xβ‚‚ : π’œ 𝔛 Ξ³ (Ξ± βˆ™ Ξ² βˆ™ Ξ³ βˆ™ Ξ“)
  xβ‚‚ = π‘£π‘Žπ‘Ÿ (old (old new))
  x₃ : π’œ 𝔛 Ξ΄ (Ξ± βˆ™ Ξ² βˆ™ Ξ³ βˆ™ Ξ΄ βˆ™ Ξ“)
  x₃ = π‘£π‘Žπ‘Ÿ (old (old (old new)))
  xβ‚„ : π’œ 𝔛 Ο… (Ξ± βˆ™ Ξ² βˆ™ Ξ³ βˆ™ Ξ΄ βˆ™ Ο… βˆ™ Ξ“)
  xβ‚„ = π‘£π‘Žπ‘Ÿ (old (old (old (old new))))