module A201606.Common.OrderPreservingEmbedding where

open import A201606.Common.Context public

open import Relation.Binary.PropositionalEquality using (_≡_ ; refl ; cong)


-- Order-preserving embeddings (OPEs).

module _ {𝕌 : Set} where
  infix 1 _⊆_
  data _⊆_ : Cx 𝕌  Cx 𝕌  Set where
    done :   
    skip :  {A Γ Γ′}  Γ  Γ′  Γ  Γ′ , A
    keep :  {A Γ Γ′}  Γ  Γ′  Γ , A  Γ′ , A

  refl⊆ :  {Γ}  Γ  Γ
  refl⊆ {}     = done
  refl⊆ {Γ , A} = keep refl⊆

  trans⊆ :  {Γ Γ′ Γ″}  Γ  Γ′  Γ′  Γ″  Γ  Γ″
  trans⊆ η        done      = η
  trans⊆ η        (skip η′) = skip (trans⊆ η η′)
  trans⊆ (skip η) (keep η′) = skip (trans⊆ η η′)
  trans⊆ (keep η) (keep η′) = keep (trans⊆ η η′)

  zero⊆ :  {Γ}    Γ
  zero⊆ {}     = done
  zero⊆ {Γ , A} = skip zero⊆

  drop⊆ :  {A Γ Γ′}  Γ , A  Γ′  Γ  Γ′
  drop⊆ (skip η) = skip (drop⊆ η)
  drop⊆ (keep η) = skip η

  keep⊆ :  {A Γ Γ′}  Γ , A  Γ′ , A  Γ  Γ′
  keep⊆ (skip η) = drop⊆ η
  keep⊆ (keep η) = η

  syntax trans⊆ η η′ = η′  η

  id₁• :  {Γ Γ′}  (η : Γ  Γ′)  η  refl⊆  η
  id₁• done     = refl
  id₁• (skip η) = cong skip (id₁• η)
  id₁• (keep η) = cong keep (id₁• η)

  id₂• :  {Γ Γ′}  (η : Γ  Γ′)  refl⊆  η  η
  id₂• done     = refl
  id₂• (skip η) = cong skip (id₂• η)
  id₂• (keep η) = cong keep (id₂• η)

  assoc• :  {Γ Γ′ Γ″ Γ‴}  (η : Γ  Γ′) (η′ : Γ′  Γ″) (η″ : Γ″  Γ‴)  (η″  η′)  η  η″  (η′  η)
  assoc• η        η′        done      = refl
  assoc• η        η′        (skip η″) = cong skip (assoc• η η′ η″)
  assoc• η        (skip η′) (keep η″) = cong skip (assoc• η η′ η″)
  assoc• (skip η) (keep η′) (keep η″) = cong skip (assoc• η η′ η″)
  assoc• (keep η) (keep η′) (keep η″) = cong keep (assoc• η η′ η″)

  ren-var :  {Γ Γ′}  Γ  Γ′  Renᵢ Γ Γ′
  ren-var done     ()
  ren-var (skip η) i       = pop (ren-var η i)
  ren-var (keep η) top     = top
  ren-var (keep η) (pop i) = pop (ren-var η i)

  ren-var-refl⊆ :  {A Γ}  (i : A  Γ)  ren-var refl⊆ i  i
  ren-var-refl⊆ top     = refl
  ren-var-refl⊆ (pop i) = cong pop (ren-var-refl⊆ i)

  ren-var-trans⊆ :  {A Γ Γ′ Γ″}  (η : Γ  Γ′) (η′ : Γ′  Γ″) (i : A  Γ)  ren-var η′ (ren-var η i)  ren-var (η′  η) i
  ren-var-trans⊆ done     η′        ()
  ren-var-trans⊆ η        (skip η′) i       = cong pop (ren-var-trans⊆ η η′ i)
  ren-var-trans⊆ (skip η) (keep η′) i       = cong pop (ren-var-trans⊆ η η′ i)
  ren-var-trans⊆ (keep η) (keep η′) top     = refl
  ren-var-trans⊆ (keep η) (keep η′) (pop i) = cong pop (ren-var-trans⊆ η η′ i)