module Term.Weakening.Properties where
open import Prelude
open import Term
open import Term.Weakening renaming (lookup to lookupW)
open ≡-Reasoning
private
variable
a b : Ty
Γ Δ Δ₁ Δ₂ Φ : Context
x : a ∈ Γ
t : Term Γ a
ρ ρ' ρ₁ ρ₂ ρ₃ : Wk Γ Δ
Wk-cons-inv : Wk Γ (a ∷ Δ) → ∃ λ Γ₁ → ∃ λ Γ₂ → (Γ ≡ Γ₁ ++ a ∷ Γ₂) × Wk Γ₂ Δ
Wk-cons-inv (skip ρ) with Wk-cons-inv ρ
... | Γ₁ , Γ₂ , refl , ρ' = (_ ∷ Γ₁) , _ , refl , ρ'
Wk-cons-inv (keep ρ) = [] , _ , refl , ρ
Wk-append-inv : Wk Γ (Δ₁ ++ a ∷ Δ₂) → ∃ λ Γ₁ → ∃ λ Γ₂ → (Γ ≡ Γ₁ ++ a ∷ Γ₂) × Wk Γ₂ Δ₂
Wk-append-inv {Δ₁ = []} ρ = Wk-cons-inv ρ
Wk-append-inv {Δ₁ = a ∷ Δ₁} (skip ρ) with Wk-append-inv {Δ₁ = a ∷ Δ₁} ρ
... | Γ₁ , Γ₂ , refl , ρ' = _ ∷ _ , _ , refl , ρ'
Wk-append-inv {Δ₁ = a ∷ Δ₁} (keep ρ) with Wk-append-inv ρ
... | Γ₁ , Γ₂ , refl , ρ' = _ ∷ _ , _ , refl , ρ'
{-# TERMINATING #-}
Wk-append : Wk Γ (Δ ++ a ∷ Γ) → ⊥
Wk-append ρ with Wk-append-inv ρ
... | Γ₁ , Γ₂ , refl , ρ' = Wk-append ρ'
Wk-cons : Wk Γ (a ∷ Γ) → ⊥
Wk-cons ρ = Wk-append {Δ = []} ρ
Wk-anti-sym : Wk Γ Δ → Wk Δ Γ → Γ ≡ Δ
Wk-anti-sym (skip ρ) ρ' = case Wk-cons (compWW ρ ρ') of λ()
Wk-anti-sym (keep ρ) (skip ρ') = case Wk-cons (compWW ρ ρ') of λ()
Wk-anti-sym (keep ρ) (keep ρ') = cong (_ ∷_) (Wk-anti-sym ρ ρ')
Wk-anti-sym done done = refl
Wk-anti-sym-uniq : (ρ : Wk Γ Δ) (ρ' : Wk Δ Γ)
→ ∃ λ (eq : Γ ≡ Δ) → subst (λ Γ → Wk Γ Δ) eq ρ
≡ subst (λ Γ → Wk Δ Γ) eq ρ'
Wk-anti-sym-uniq (skip ρ) ρ' = case Wk-cons (compWW ρ ρ') of λ()
Wk-anti-sym-uniq (keep ρ) (skip ρ') = case Wk-cons (compWW ρ ρ') of λ()
Wk-anti-sym-uniq (keep ρ) (keep ρ') with Wk-anti-sym-uniq ρ ρ'
... | refl , refl = refl , refl
Wk-anti-sym-uniq done done = refl , refl
lookup-idW : lookupW idW x ≡ x
lookup-idW {x = zero} = refl
lookup-idW {x = suc x} = cong suc lookup-idW
wk-idW : wk idW t ≡ t
wk-idW {t = var x} = cong var lookup-idW
wk-idW {t = abs t} = cong abs wk-idW
wk-idW {t = app t u} = cong₂ app wk-idW wk-idW
comp-W-idW : compWW ρ idW ≡ ρ
comp-W-idW {ρ = done} = refl
comp-W-idW {ρ = skip ρ} = cong skip comp-W-idW
comp-W-idW {ρ = keep ρ} = cong keep comp-W-idW
comp-idW-W : compWW idW ρ ≡ ρ
comp-idW-W {ρ = done} = refl
comp-idW-W {ρ = skip ρ} = cong skip comp-idW-W
comp-idW-W {ρ = keep ρ} = cong keep comp-idW-W
idW-unique : (ρ ρ' : Wk Γ Γ) → ρ ≡ ρ'
idW-unique ρ ρ' with Wk-anti-sym-uniq ρ ρ'
... | refl , refl = refl
lookup-id : {ρ : Wk Γ Γ} → lookupW ρ x ≡ x
lookup-id {x = x} {ρ = ρ} = subst (λ ρ → lookupW ρ x ≡ x) (idW-unique idW ρ) lookup-idW
wk-id : {ρ : Wk Γ Γ} → wk ρ t ≡ t
wk-id {t = t} {ρ = ρ} = subst (λ ρ → wk ρ t ≡ t) (idW-unique idW ρ) wk-idW
comp-W-id : {ρ' : Wk Γ Γ} → compWW ρ ρ' ≡ ρ
comp-W-id {ρ = ρ} {ρ' = ρ'} = subst (λ ρ' → compWW ρ ρ' ≡ ρ) (idW-unique idW ρ') comp-W-idW
comp-id-W : {ρ : Wk Γ Γ} → compWW ρ ρ' ≡ ρ'
comp-id-W {ρ' = ρ'} {ρ = ρ} = subst (λ ρ → compWW ρ ρ' ≡ ρ') (idW-unique idW ρ) comp-idW-W
lookupW-lookupW : lookupW (compWW ρ ρ') x ≡ lookupW ρ (lookupW ρ' x)
lookupW-lookupW {ρ = skip ρ} = cong suc (lookupW-lookupW {ρ = ρ})
lookupW-lookupW {ρ = keep ρ} {ρ' = skip ρ'} = cong suc (lookupW-lookupW {ρ = ρ})
lookupW-lookupW {ρ = keep ρ} {ρ' = keep ρ'} {x = suc x} = cong suc (lookupW-lookupW {ρ = ρ})
lookupW-lookupW {ρ = keep ρ} {ρ' = keep ρ'} {x = zero} = refl
lookupW-lookupW {ρ = done} {ρ' = done} {x = ()}
wk-wk : wk (compWW ρ ρ') t ≡ wk ρ (wk ρ' t)
wk-wk {t = var x} = cong var (lookupW-lookupW {x = x})
wk-wk {t = abs t} = cong abs (wk-wk {t = t})
wk-wk {t = app t u} = cong₂ app wk-wk wk-wk
assocWWW : compWW (compWW ρ₁ ρ₂) ρ₃ ≡ compWW ρ₁ (compWW ρ₂ ρ₃)
assocWWW {ρ₁ = done} {ρ₂ = ρ₂} {ρ₃ = ρ₃} = refl
assocWWW {ρ₁ = skip ρ₁} {ρ₂ = ρ₂} {ρ₃ = ρ₃} = cong skip (assocWWW {ρ₁ = ρ₁})
assocWWW {ρ₁ = keep ρ₁} {ρ₂ = skip ρ₂} {ρ₃ = ρ₃} = cong skip (assocWWW {ρ₁ = ρ₁})
assocWWW {ρ₁ = keep ρ₁} {ρ₂ = keep ρ₂} {ρ₃ = skip ρ₃} = cong skip (assocWWW {ρ₁ = ρ₁})
assocWWW {ρ₁ = keep ρ₁} {ρ₂ = keep ρ₂} {ρ₃ = keep ρ₃} = cong keep (assocWWW {ρ₁ = ρ₁})
wk1-wk : wk1 {a = a} (wk ρ t) ≡ wk (keep ρ) (wk1 t)
wk1-wk {ρ = ρ} {t = t} =
wk1 (wk ρ t) ≡⟨ sym wk-wk ⟩
wk (compWW skip1 ρ) t ≡⟨ cong (λ ρ → wk ρ t) (comp-id-W {ρ = idW}) ⟩
wk (skip ρ) t ≡⟨ cong (λ ρ → wk (skip ρ) t) (sym (comp-W-id {ρ' = idW})) ⟩
wk (compWW (keep ρ) skip1) t ≡⟨ wk-wk ⟩
wk (keep ρ) (wk1 t) ∎