module ETU.Uniqueness where

open import Prelude
open import WSLN

open import ETU.Syntax
open import ETU.Judgement
open import ETU.Rules
open import ETU.Ok
open import ETU.WellScoped
open import ETU.Weakening
open import ETU.Substitution
open import ETU.Admissible
open import ETU.ExistsFresh

----------------------------------------------------------------------
-- Types of terms are unique up to definitional equality
-- and have a unique level
----------------------------------------------------------------------
svVr :
 {l l' : โ„•}
 {ฮ“ : Cx}
 {A A' : Ty}
 {x x' : ๐”ธ}
 (_ : Ok ฮ“)
 (_ : (x , A , l) isIn ฮ“)
 (_ : (x' , A' , l') isIn ฮ“)
 (_ : x โ‰ก x')
 โ†’ -------------------------
 (l โ‰ก l') โˆง (A โ‰ก A')

svVr _ isInNew isInNew _ = refl , refl
svVr (okโจŸ _ q _) isInNew (isInOld p') refl =
  ร˜elim (โˆ‰โ†’ยฌโˆˆ q (isInโ†’dom p'))
svVr (okโจŸ _ q _) (isInOld p) isInNew refl =
  ร˜elim (โˆ‰โ†’ยฌโˆˆ q (isInโ†’dom p))
svVr (okโจŸ _ _ q) (isInOld p) (isInOld p') e = svVr q p p' e

svTy :
  {l l' : โ„•}
  {ฮ“ : Cx}
  {A A' : Ty}
  {a : Tm}
  (_ : ฮ“ โŠข a โˆถ A โฆ‚ l)
  (_ : ฮ“ โŠข a โˆถ A' โฆ‚ l')
  โ†’ ---------------------------
  (l โ‰ก l') โˆง (ฮ“ โŠข A ๏ผ A' โฆ‚ l)

svTy (โŠขconv qโ‚€ qโ‚) q' with (refl , q) โ† svTy qโ‚€ q' =
  (refl , Trans (Symm qโ‚) q)

svTy q (โŠขconv qโ‚€' qโ‚') with (refl , q') โ† svTy q qโ‚€' =
  (refl , Trans q' qโ‚')

svTy (โŠข๐ฏ qโ‚€ qโ‚) (โŠข๐ฏ _ qโ‚')
  with (refl , refl) โ† svVr qโ‚€ qโ‚ qโ‚' refl =
  (refl , Refl (okโ†’ty qโ‚€ qโ‚))

svTy (โŠข๐” q) (โŠข๐” _) = (refl , Refl (โŠข๐” q))

svTy (โŠข๐šท _ qโ‚€ _) (โŠข๐šท _ _ _) = (refl , Refl (โŠข๐” (โŠขok qโ‚€)))

svTy (โŠข๐›Œ{B = B} S qโ‚€ qโ‚ _) (โŠข๐›Œ{B = B'} S' qโ‚€' qโ‚' _)
  with (refl , _ ) โ† svTy qโ‚ qโ‚'
  | (x , x#S โˆ‰โˆช x#S' โˆ‰โˆช x#) โ† fresh (S , S' , B , B')
  with (refl , r) โ† svTy (qโ‚€ x x#S) (qโ‚€' x x#S') =
  refl , (๐šทCongโป (Refl qโ‚) r x#)

svTy (โŠขโˆ™{B = B} S _ qโ‚ qโ‚‚ _) (โŠขโˆ™ S' _ qโ‚' qโ‚‚' _)
  with (refl , _) โ† svTy qโ‚ qโ‚'
  | (x , x#S โˆ‰โˆช x#S' โˆ‰โˆช x#) โ† fresh (S , S' , B)
  with (refl , _) โ† svTy (qโ‚‚ x x#S) (qโ‚‚' x x#S') =
  (refl , Refl (concTy B x (qโ‚‚ x x#S) qโ‚ x#))

svTy (โŠข๐„๐ช q _ _) (โŠข๐„๐ช q' _ _)
  with (refl , _) โ† svTy q q' =
  (refl , Refl (โŠข๐” (โŠขok q)))

svTy (โŠข๐ซ๐ž๐Ÿ๐ฅ q _) (โŠข๐ซ๐ž๐Ÿ๐ฅ q' _)
  with (refl , r) โ† svTy q q' =
  (refl , ๐„๐ชCong r (Refl q) (Refl q))

svTy (โŠข๐„๐ฆ๐ฉ q) (โŠข๐„๐ฆ๐ฉ _) = (refl , Refl (โŠข๐” q))

svTy (โŠข๐ž๐ฆ๐ฉ q _) (โŠข๐ž๐ฆ๐ฉ q' _)
  with (refl , _) โ† svTy q q' = refl , Refl q

svTy (โŠข๐๐š๐ญ q) (โŠข๐๐š๐ญ _) = (refl , Refl (โŠข๐” q))

svTy (โŠข๐ณ๐ž๐ซ๐จ q) (โŠข๐ณ๐ž๐ซ๐จ _) = (refl , Refl (โŠข๐๐š๐ญ q))

svTy (โŠข๐ฌ๐ฎ๐œ๐œ q) (โŠข๐ฌ๐ฎ๐œ๐œ _) = (refl , Refl (โŠข๐๐š๐ญ (โŠขok q)))

svTy (โŠข๐ง๐ซ๐ž๐œ{C = C} S qโ‚€ _ qโ‚‚ h) (โŠข๐ง๐ซ๐ž๐œ _ qโ‚€' _ _ _)
  with (refl , _) โ† svTy qโ‚€ qโ‚€'
  | (x , x#S โˆ‰โˆช x#) โ† fresh (S , C) =
  (refl , Refl (concTy C x (h x x#S) qโ‚‚ x#))