module Scoped.Extrication.RenamingSubstitution where
erasure commutes with renaming/substitution
open import Data.Nat using (ℕ) open import Data.Fin using (Fin;zero;suc) open import Data.Vec using (Vec;[];_∷_) open import Data.Product using (Σ;proj₁;proj₂) renaming (_,_ to _,,_) open import Function using (_∘_) open import Relation.Binary.PropositionalEquality as Eq using (_≡_;refl;sym;trans;cong;cong₂) open import Utils using (Kind;*) open import Utils.List using (List;[];_∷_) open import Type using (Ctx⋆;_,⋆_;_∋⋆_;Z;S) open import Algorithmic using (Ctx;_⊢_) open Ctx import Algorithmic.RenamingSubstitution as As import Type.RenamingSubstitution as T open import Type.BetaNormal using (_⊢Nf⋆_;_⊢Ne⋆_;renNf;renNe;renNf-VecList;renNf-List) open _⊢Nf⋆_ open _⊢Ne⋆_ open import Type.BetaNBE.RenamingSubstitution using (extsNf) open import Scoped using (ScopedTy) open ScopedTy open import Scoped.Extrication using (len⋆;extricateVar⋆;extricateNf⋆;extricateNe⋆;extricate;extricateNf⋆-VecList;extricateNf⋆-List) open import Scoped.RenamingSubstitution as SS using (Ren⋆;lift⋆;ren⋆;ren⋆-cong;Sub⋆;slift⋆;ren⋆-List;ren⋆-ListList) import Builtin.Constant.Type as AC import Builtin.Constant.Type as SC -- type renamings backVar : ∀{Γ} → Fin (len⋆ Γ) → Σ Kind λ J → Γ ∋⋆ J backVar {Γ ,⋆ K} zero = K ,, Z backVar {Γ ,⋆ K} (suc i) = let J ,, α = backVar i in J ,, S α lem-backVar₁ : ∀{Γ J}(α : Γ ∋⋆ J) → proj₁ (backVar (extricateVar⋆ α)) ≡ J lem-backVar₁ Z = refl lem-backVar₁ (S α) = lem-backVar₁ α lem-S : ∀{Φ K J J'} → (p : J ≡ J') → (α : Φ ∋⋆ J) → S (Eq.subst (Φ ∋⋆_) p α) ≡ Eq.subst (Φ ,⋆ K ∋⋆_) p (S α) lem-S refl α = refl lem-backVar : ∀{Γ J}(α : Γ ∋⋆ J) → Eq.subst (Γ ∋⋆_) (lem-backVar₁ α) (proj₂ (backVar (extricateVar⋆ α))) ≡ α lem-backVar Z = refl lem-backVar (S α) = trans (sym (lem-S (lem-backVar₁ α) (proj₂ (backVar (extricateVar⋆ α))))) (cong S (lem-backVar α)) extricateRenNf⋆ : ∀{Γ Δ}(ρ⋆ : ∀ {J} → Γ ∋⋆ J → Δ ∋⋆ J) → Ren⋆ (len⋆ Γ) (len⋆ Δ) extricateRenNf⋆ ρ⋆ x = extricateVar⋆ (ρ⋆ (proj₂ (backVar x))) lift⋆-ext : ∀{Γ Δ K} → (ρ⋆ : ∀ {J} → Γ ∋⋆ J → Δ ∋⋆ J) → (α : Fin (len⋆ (Γ ,⋆ K))) → lift⋆ (extricateRenNf⋆ ρ⋆) α ≡ extricateRenNf⋆ (T.ext ρ⋆ {K = K}) α -- lift⋆-ext ρ⋆ zero = refl lift⋆-ext ρ⋆ (suc α) = refl lem-extricateVar⋆ : ∀{Γ Δ J J'} → (ρ⋆ : ∀ {J} → Γ ∋⋆ J → Δ ∋⋆ J) → (α : Γ ∋⋆ J) → (p : J ≡ J') → extricateVar⋆ (ρ⋆ α) ≡ extricateVar⋆ (ρ⋆ (Eq.subst (Γ ∋⋆_) p α)) lem-extricateVar⋆ ρ⋆ α refl = refl ren-extricateNf⋆ : ∀{Γ Δ J} → (ρ⋆ : ∀ {J} → Γ ∋⋆ J → Δ ∋⋆ J) → (A : Γ ⊢Nf⋆ J) → ren⋆ (extricateRenNf⋆ ρ⋆) (extricateNf⋆ A) ≡ extricateNf⋆ (renNf ρ⋆ A) ren-extricateNe⋆ : ∀{Γ Δ J} → (ρ⋆ : ∀ {J} → Γ ∋⋆ J → Δ ∋⋆ J) → (A : Γ ⊢Ne⋆ J) → ren⋆ (extricateRenNf⋆ ρ⋆) (extricateNe⋆ A) ≡ extricateNe⋆ (renNe ρ⋆ A) ren-extricateNe⋆ ρ⋆ (` x) = cong ` (trans (lem-extricateVar⋆ ρ⋆ (proj₂ (backVar (extricateVar⋆ x))) (lem-backVar₁ x)) (cong (extricateVar⋆ ∘ ρ⋆) (lem-backVar x))) ren-extricateNe⋆ ρ⋆ (A · B) = cong₂ _·_ (ren-extricateNe⋆ ρ⋆ A) (ren-extricateNf⋆ ρ⋆ B) ren-extricateNe⋆ ρ⋆ (^ x) = refl ren-extricateNf⋆-List : ∀{Γ Δ J} → (ρ⋆ : ∀ {J} → Γ ∋⋆ J → Δ ∋⋆ J) → (xs : List (Γ ⊢Nf⋆ J)) → ren⋆-List (extricateRenNf⋆ ρ⋆) (extricateNf⋆-List xs) ≡ extricateNf⋆-List (renNf-List ρ⋆ xs) ren-extricateNf⋆-List ρ⋆ [] = refl ren-extricateNf⋆-List ρ⋆ (x ∷ xs) = cong₂ Utils._∷_ (ren-extricateNf⋆ ρ⋆ x) (ren-extricateNf⋆-List ρ⋆ xs) ren-extricateNf⋆-ListList : ∀{Γ Δ J}{n} → (ρ⋆ : ∀ {J} → Γ ∋⋆ J → Δ ∋⋆ J) → (A : Vec (List (Γ ⊢Nf⋆ J)) n) → ren⋆-ListList (extricateRenNf⋆ ρ⋆) (extricateNf⋆-VecList A) ≡ extricateNf⋆-VecList (renNf-VecList ρ⋆ A) ren-extricateNf⋆-ListList ρ⋆ [] = refl ren-extricateNf⋆-ListList ρ⋆ (xs ∷ xss) = cong₂ Utils._∷_ (ren-extricateNf⋆-List ρ⋆ xs) (ren-extricateNf⋆-ListList ρ⋆ xss) ren-extricateNf⋆ ρ⋆ (Π A) = cong (Π _) (trans (ren⋆-cong (lift⋆-ext ρ⋆) (extricateNf⋆ A)) (ren-extricateNf⋆ (T.ext ρ⋆) A)) ren-extricateNf⋆ ρ⋆ (A ⇒ B) = cong₂ _⇒_ (ren-extricateNf⋆ ρ⋆ A) (ren-extricateNf⋆ ρ⋆ B) ren-extricateNf⋆ ρ⋆ (ƛ A) = cong (ƛ _) (trans (ren⋆-cong (lift⋆-ext ρ⋆) (extricateNf⋆ A)) (ren-extricateNf⋆ (T.ext ρ⋆) A)) ren-extricateNf⋆ ρ⋆ (ne A) = ren-extricateNe⋆ ρ⋆ A ren-extricateNf⋆ ρ⋆ (con (ne x)) = ren-extricateNe⋆ ρ⋆ x ren-extricateNf⋆ ρ⋆ (μ A B) = cong₂ μ (ren-extricateNf⋆ ρ⋆ A) (ren-extricateNf⋆ ρ⋆ B) ren-extricateNf⋆ ρ⋆ (SOP xss) = cong SOP (ren-extricateNf⋆-ListList ρ⋆ xss) extricateSubNf⋆ : ∀{Γ Δ}(σ⋆ : ∀ {J} → Γ ∋⋆ J → Δ ⊢Nf⋆ J) → Sub⋆ (len⋆ Γ) (len⋆ Δ) extricateSubNf⋆ σ⋆ α = extricateNf⋆ (σ⋆ (proj₂ (backVar α))) suclem : ∀{Δ K} → (x : Fin (len⋆ Δ)) → Fin.suc x ≡ extricateRenNf⋆ (λ {J} → S {K = K}) x suclem {Δ ,⋆ _} zero = refl suclem {Δ ,⋆ _} {K} (suc x) = cong suc (suclem {Δ}{K} x) slift⋆-exts : ∀{Γ Δ K} → (σ⋆ : ∀ {J} → Γ ∋⋆ J → Δ ⊢Nf⋆ J) → (α : Fin (len⋆ (Γ ,⋆ K))) → slift⋆ (extricateSubNf⋆ σ⋆) α ≡ extricateSubNf⋆ (extsNf σ⋆ {K = K}) α -- slift⋆-exts σ⋆ zero = refl slift⋆-exts {K = K} σ⋆ (suc α) = trans (ren⋆-cong (suclem {K = K}) (extricateNf⋆ (σ⋆ (proj₂ (backVar α))))) (ren-extricateNf⋆ S (σ⋆ (proj₂ (backVar α)))) {- sub-extricateNf⋆ : ∀{Γ Δ J} → (σ⋆ : ∀ {J} → Γ ∋⋆ J → Δ ⊢Nf⋆ J) → (A : Γ ⊢Nf⋆ J) → sub⋆ (extricateSubNf⋆ σ⋆) (extricateNf⋆ A) ≡ extricateNf⋆ (substNf σ⋆ A) sub-extricateNe⋆ : ∀{Γ Δ J} → (σ⋆ : ∀ {J} → Γ ∋⋆ J → Δ ⊢Nf⋆ J) → (A : Γ ⊢NeN⋆ J) → sub⋆ (extricateSubNf⋆ σ⋆) (extricateNe⋆ A) ≡ extricateNf⋆ (nf (T.subst (embNf ∘ σ⋆) (embNeN A))) sub-extricateNe⋆ σ⋆ (` x) = {!!} sub-extricateNe⋆ σ⋆ (A · B) = trans (cong₂ _·_ (sub-extricateNe⋆ σ⋆ A) (sub-extricateNf⋆ σ⋆ B)) {!!} sub-extricateNe⋆ σ⋆ μ1 = refl sub-extricateNf⋆ σ⋆ (Π {K = K} x A) = cong (Π x (extricateK _)) (trans (trans (sub⋆-cong (slift⋆-exts σ⋆) (extricateNf⋆ A)) (sub-extricateNf⋆ (extsNf σ⋆) A)) (cong extricateNf⋆ {x = substNf (extsNf σ⋆) A}{y = reify (eval (T.subst (T.exts (embNf ∘ σ⋆)) (embNf A)) (exte (idEnv _)))} (trans (subst-eval (embNf A) idCR (embNf ∘ extsNf σ⋆)) (trans (idext (λ { Z → reflectCR (refl {x = ` Z}) ; (S α) → transCR (transCR (evalCRSubst idCR (ren-embNf S (σ⋆ α))) (ren-eval (embNf (σ⋆ α)) idCR S)) (transCR (symCR (ren-eval (embNf (σ⋆ α)) idCR S)) (idext (λ { Z → reflectCR (refl {x = ` Z}) ; (S β) → symCR (renVal-reflect S (` β))}) (T.weaken (embNf (σ⋆ α)))))}) (embNf A)) (sym (subst-eval (embNf A) (CR,,⋆ (renCR S ∘ idCR) (reflectCR (refl {x = ` Z}))) (T.exts (embNf ∘ σ⋆)))))))) sub-extricateNf⋆ σ⋆ (A ⇒ B) = cong₂ _⇒_ (sub-extricateNf⋆ σ⋆ A) (sub-extricateNf⋆ σ⋆ B) sub-extricateNf⋆ σ⋆ (ƛ {K = K} x A) = cong (ƛ x (extricateK _)) (trans (sub⋆-cong (slift⋆-exts σ⋆) (extricateNf⋆ A)) (trans (sub-extricateNf⋆ (extsNf σ⋆) A) (cong extricateNf⋆ {x = substNf (extsNf σ⋆) A}{y = reify (eval (T.subst (T.exts (embNf ∘ σ⋆)) (embNf A)) ((renVal S ∘ idEnv _) ,,⋆ fresh))} (reifyCR (transCR (subst-eval (embNf A) idCR (embNf ∘ extsNf σ⋆)) (transCR (idext (λ { Z → reflectCR {K = K} (refl {x = ` Z}) ; (S α) → transCR (transCR (evalCRSubst idCR (ren-embNf S (σ⋆ α))) (ren-eval (embNf (σ⋆ α)) idCR S)) (transCR (symCR (ren-eval (embNf (σ⋆ α)) idCR S)) (idext (λ { Z → reflectCR (refl {x = ` Z}) ; (S β) → symCR (renVal-reflect S (` β))}) (T.weaken (embNf (σ⋆ α)))) ) }) (embNf A)) (symCR (subst-eval (embNf A) (CR,,⋆ (renCR S ∘ idCR) (reflectCR {K = K} (refl {x = ` Z}))) (T.exts (embNf ∘ σ⋆))))) ))))) sub-extricateNf⋆ σ⋆ (ne A) = {!!} sub-extricateNf⋆ σ⋆ (con c) = refl -} {- -- term level renamings extricateRen : ∀{Φ Ψ Γ Δ}(ρ⋆ : ∀ {J} → Φ ∋⋆ J → Ψ ∋⋆ J) → (ρ : ∀{J}{A : Φ ⊢Nf⋆ J} → Γ ∋ A → Δ ∋ renNf ρ⋆ A) → SS.Ren (len Γ) (len Δ) extricateRen {Γ = Γ ,⋆ J} {Δ} ρ⋆ ρ (T x) = extricateRen (ρ⋆ ∘ S) (λ {_}{A} x → Eq.subst (Δ ∋_) (sym (renNf-comp A)) (ρ (T x))) x extricateRen {Γ = Γ , A} {Δ} ρ⋆ ρ Z = extricateVar (ρ Z) extricateRen {Γ = Γ , A} {Δ} ρ⋆ ρ (S x) = extricateRen ρ⋆ (ρ ∘ S) x -} -- these are the two properties of extrication/ren/sub needed to define -- extricate—→ postulate lem[] : ∀{Φ Γ}{A B : Φ ⊢Nf⋆ *}(N : Γ , A ⊢ B)(W : Γ ⊢ A) → extricate N SS.[ extricate W ] ≡ extricate (N As.[ W ]) lem[]⋆ : ∀{Φ Γ K}{B : Φ ,⋆ K ⊢Nf⋆ *}(N : Γ ,⋆ K ⊢ B)(A : Φ ⊢Nf⋆ K) → extricate N SS.[ extricateNf⋆ A ]⋆ ≡ extricate (N As.[ A ]⋆)