------------------------------------------------------------------------
-- If Definition.Untyped.QuantityTranslation is instantiated with
-- identity functions, then the translations are pointwise equal to
-- identity functions or glassification
------------------------------------------------------------------------

open import Tools.Bool

module Definition.Untyped.QuantityTranslation.Identity
  {a} (M : Set a)
  (transparent : Bool)
  where

open import Tools.Fin
open import Tools.Function
open import Tools.Nat
open import Tools.PropositionalEquality
open import Tools.Relation

open import Definition.Untyped M
open import Definition.Untyped.Properties M
open import
  Definition.Untyped.QuantityTranslation {M₁ = M} transparent idᶠ idᶠ

private variable
  p   : M
  c   : Constructor _ _
  t   : Term[ _ ] _
  k   : Term-kind
  ts  : Args _ _
     : DCon (Term 0) _
  Δ   : Con Term _
  Γ   : Cons _ _
  σ   : Subst _ _
  o   : Opacity _
  m n : Nat
  x   : Fin _

opaque

  -- The function tr-BinderMode b is pointwise equal to an identity
  -- function.

  tr-BinderMode-id :  b  tr-BinderMode b p  p
  tr-BinderMode-id BMΠ     = refl
  tr-BinderMode-id (BMΣ _) = refl

opaque

  -- The function tr-Constructor is pointwise equal to an identity
  -- function.

  tr-Constructor-id : tr-Constructor c  c
  tr-Constructor-id {c = defnᵏ _}        = refl
  tr-Constructor-id {c = Levelᵏ}         = refl
  tr-Constructor-id {c = zeroᵘᵏ}         = refl
  tr-Constructor-id {c = sucᵘᵏ}          = refl
  tr-Constructor-id {c = supᵘᵏ}          = refl
  tr-Constructor-id {c = ωᵘ+ᵏ _}         = refl
  tr-Constructor-id {c = levelᵏ}         = refl
  tr-Constructor-id {c = Uᵏ}             = refl
  tr-Constructor-id {c = Liftᵏ}          = refl
  tr-Constructor-id {c = liftᵏ}          = refl
  tr-Constructor-id {c = lowerᵏ}         = refl
  tr-Constructor-id {c = Emptyᵏ}         = refl
  tr-Constructor-id {c = emptyrecᵏ _}    = refl
  tr-Constructor-id {c = Unitᵏ _}        = refl
  tr-Constructor-id {c = starᵏ _}        = refl
  tr-Constructor-id {c = unitrecᵏ _ _}   = refl
  tr-Constructor-id {c = ΠΣᵏ b _ _}      = cong (flip (ΠΣᵏ _) _) $
                                           tr-BinderMode-id b
  tr-Constructor-id {c = lamᵏ _}         = refl
  tr-Constructor-id {c = appᵏ _}         = refl
  tr-Constructor-id {c = prodᵏ _ _}      = refl
  tr-Constructor-id {c = fstᵏ _}         = refl
  tr-Constructor-id {c = sndᵏ _}         = refl
  tr-Constructor-id {c = prodrecᵏ _ _ _} = refl
  tr-Constructor-id {c = ℕᵏ}             = refl
  tr-Constructor-id {c = zeroᵏ}          = refl
  tr-Constructor-id {c = sucᵏ}           = refl
  tr-Constructor-id {c = natrecᵏ _ _ _}  = refl
  tr-Constructor-id {c = Idᵏ}            = refl
  tr-Constructor-id {c = rflᵏ}           = refl
  tr-Constructor-id {c = Jᵏ _ _}         = refl
  tr-Constructor-id {c = Kᵏ _}           = refl
  tr-Constructor-id {c = []-congᵏ _}     = refl
  tr-Constructor-id {c = Quotᵏ}          = refl
  tr-Constructor-id {c = classᵏ}         = refl
  tr-Constructor-id {c = respᵏ}          = refl
  tr-Constructor-id {c = setᵏ}           = refl
  tr-Constructor-id {c = qrecᵏ}          = refl

opaque mutual

  -- The function tr-Term′ is pointwise equal to an identity function.

  tr-Term′-id :  {n} {t : Term[ k ]′ n}  tr-Term′ t  t
  tr-Term′-id {t = var _}   = refl
  tr-Term′-id {t = con _ _} = cong₂ con tr-Constructor-id tr-Args-id

  -- The function tr-Args is pointwise equal to an identity function.

  tr-Args-id : tr-Args ts  ts
  tr-Args-id {ts = []}     = refl
  tr-Args-id {ts = _ ∷ₜ _} = cong₂ _∷ₜ_ tr-Term′-id tr-Args-id

opaque

  -- The function tr-Term is pointwise equal to an identity function.

  tr-Term-id : tr-Term t  t
  tr-Term-id {t} rewrite tr-Term′-id {t = fromTerm t} =
    toTerm∘fromTerm _

opaque

  -- The function tr-Con is pointwise equal to an identity function.

  tr-Con-id : tr-Con Δ  Δ
  tr-Con-id {Δ = ε}     = refl
  tr-Con-id {Δ = _  _} = cong₂ _∙_ tr-Con-id tr-Term-id

opaque

  -- The function tr-Subst is pointwise equal to an identity function.

  tr-Subst-id : (σ : Subst m n)  tr-Subst σ x  σ x
  tr-Subst-id _ = tr-Term-id

-- The following results hold if definitions are not made transparent.

module Not-transparent (not-transparent : ¬ T transparent) where

  opaque

    -- The function tr-Opacity is pointwise equal to an identity
    -- function.

    tr-Opacity-id : tr-Opacity o  o
    tr-Opacity-id = tr-Opacity-not-transparent not-transparent

  opaque

    -- The function tr-DCon is pointwise equal to an identity function.

    tr-DCon-id : tr-DCon   
    tr-DCon-id { = ε}    = refl
    tr-DCon-id { = _ ∙!} =
      cong₄ _∙⟨_⟩[_∷_] tr-DCon-id tr-Opacity-id tr-Term-id tr-Term-id

  opaque

    -- The function tr-Cons is pointwise equal to an identity function.

    tr-Cons-id : tr-Cons Γ  Γ
    tr-Cons-id = cong₂ _»_ tr-DCon-id tr-Con-id

-- The following results hold if definitions are made transparent.

module Transparent (transparent : T transparent) where

  opaque

    -- The function tr-Opacity is pointwise equal to a constant
    -- function.

    tr-Opacity-tra : (o : Opacity n)  tr-Opacity o  tra
    tr-Opacity-tra o = tr-Opacity-transparent {o = o} transparent

  opaque

    -- The function tr-DCon is pointwise equal to glassify.

    tr-DCon-glassify : tr-DCon   glassify 
    tr-DCon-glassify { = ε}         = refl
    tr-DCon-glassify { = _ ∙⟨ o ⟩!} =
      cong₄ _∙⟨_⟩[_∷_]
        tr-DCon-glassify (tr-Opacity-tra o) tr-Term-id tr-Term-id

  opaque

    -- The function tr-Cons is pointwise equal to a certain function.

    tr-Cons-glassify : tr-Cons Γ  glassify (Γ .defs) » Γ .vars
    tr-Cons-glassify = cong₂ _»_ tr-DCon-glassify tr-Con-id