module Generic.Identity where open import Size open import Agda.Builtin.List open import Data.Product hiding (zip) open import Data.Sum open import var open import rel open import varlike open import environment open import Generic.Syntax open import Generic.Semantics open import Generic.Zip open import Generic.Simulation open import Function open import Relation.Binary.PropositionalEquality as PEq open ≡-Reasoning module _ {I : Set} {d : Desc I} where data _≅_ {σ : I} {Γ : List I} : {s : Size} → Tm d s σ Γ → {t : Size} → Tm d t σ Γ → Set ⟨_⟩_≅_ : (e : Desc I) {σ : I} {Γ : List I} {s : Size} → ⟦ e ⟧ (Scope (Tm d s)) σ Γ → {t : Size} → ⟦ e ⟧ (Scope (Tm d t)) σ Γ → Set data _≅_ {σ} {Γ} where `var : {s t : Size} {k l : Var σ Γ} → k ≡ l → `var {s = s} k ≅ `var {s = t} l `con : {s t : Size} {b : ⟦ d ⟧ (Scope (Tm d s)) σ Γ} {c : ⟦ d ⟧ (Scope (Tm d t)) σ Γ} → ⟨ d ⟩ b ≅ c → `con {s = s} b ≅ `con {s = t} c ⟨ e ⟩ b ≅ c = Zip e (λ _ _ t u → t ≅ u) b c ≅⇒≡ : ∀ {σ Γ} {t u : Tm d ∞ σ Γ} → t ≅ u → t ≡ u ⟨_⟩≅⇒≡ : ∀ {σ Γ} e {t u : ⟦ e ⟧ (Scope (Tm d ∞)) σ Γ} → ⟨ e ⟩ t ≅ u → t ≡ u ≅⇒≡ (`var eq) = cong `var eq ≅⇒≡ (`con eq) = cong `con (⟨ d ⟩≅⇒≡ eq) ⟨ `σ A d ⟩≅⇒≡ (refl , eq) = cong ,_ (⟨ d _ ⟩≅⇒≡ eq) ⟨ `X Δ j d ⟩≅⇒≡ (≅-pr , eq) = cong₂ _,_ (≅⇒≡ ≅-pr) (⟨ d ⟩≅⇒≡ eq) ⟨ `∎ i ⟩≅⇒≡ eq = proof-irrelevance _ _ module RenId {I : Set} {d : Desc I} where ren-id : ∀ {s : Size} {i Γ} (t : Tm d s i Γ) {ρ : Thinning Γ Γ} → ∀[ Eq^R ] ρ (base vl^Var) → ren ρ t ≅ t ren-body-id : ∀ Δ i {Γ s} (t : Scope (Tm d s) Δ i Γ) {ρ : Thinning Γ Γ} → ∀[ Eq^R ] ρ (base vl^Var) → reify vl^Var Δ i (Sem.body Renaming ρ Δ i t) ≅ t ren-id (`var k) ρ^R = `var (trans (lookup^R ρ^R k) (lookup-base^Var k)) ren-id (`con t) ρ^R = `con (subst₂ (⟨ d ⟩_≅_) (sym $ fmap² d (Sem.body Renaming _) (reify vl^Var) _) (fmap-id d _) $ zip d (λ Δ i t → ren-body-id Δ i t ρ^R) _) ren-body-id [] i t = ren-id t ren-body-id Δ@(_ ∷ _) i {Γ} t {ρ} ρ^R = ren-id t eq^R where eq^R : ∀[ Eq^R ] (lift vl^Var Δ ρ) (base vl^Var) lookup^R eq^R k with split Δ k | inspect (split Δ) k ... | inj₁ k₁ | PEq.[ eq ] = begin injectˡ Γ (lookup (base vl^Var) k₁) ≡⟨ cong (injectˡ Γ) (lookup-base^Var k₁) ⟩ injectˡ Γ k₁ ≡⟨ injectˡ-split Δ k eq ⟩ k ≡⟨ sym (lookup-base^Var k) ⟩ lookup (base vl^Var) k ∎ ... | inj₂ k₂ | PEq.[ eq ] = begin injectʳ Δ (lookup (base vl^Var) (lookup ρ k₂)) ≡⟨ cong (injectʳ Δ) (lookup-base^Var _) ⟩ injectʳ Δ (lookup ρ k₂) ≡⟨ cong (injectʳ Δ) (lookup^R ρ^R k₂) ⟩ injectʳ Δ (lookup (base vl^Var) k₂) ≡⟨ cong (injectʳ Δ) (lookup-base^Var k₂) ⟩ injectʳ Δ k₂ ≡⟨ injectʳ-split Δ k eq ⟩ k ≡⟨ sym (lookup-base^Var k) ⟩ lookup (base vl^Var) k ∎ module _ {I : Set} {d : Desc I} where ren-id : ∀ {σ Γ} (t : Tm d ∞ σ Γ) → ren (base vl^Var) t ≡ t ren-id t = ≅⇒≡ (RenId.ren-id t (pack^R λ _ → refl)) sub-id : ∀ {σ Γ} (t : Tm d ∞ σ Γ) → sub (base vl^Tm) t ≡ t sub-id t = begin sub (base vl^Tm) t ≡⟨ sym $ Sim.sim RenSub base^VarTm^R t ⟩ ren (base vl^Var) t ≡⟨ ren-id t ⟩ t ∎