module Algorithmic.Soundness where open import Function using (_∘_) open import Data.Empty using (⊥) open import Data.Vec using (Vec;[];_∷_) open import Data.Product using (_×_) renaming (_,_ to _,,_) open import Data.Unit using (⊤;tt) open import Relation.Binary.PropositionalEquality using (_≡_;refl;sym;trans;cong;cong₂) renaming (subst to substEq) open Relation.Binary.PropositionalEquality.≡-Reasoning open import Utils using (Kind;*;♯;_⇒_) open import Utils.List using (List;[];_∷_) open import Type using (Ctx⋆;∅;_,⋆_;_⊢⋆_;_∋⋆_;S;Z) open _⊢⋆_ open import Type.RenamingSubstitution using (_[_];sub-cons;sub-cong;weaken;sub;sub∅) open import Type.Equality using (_≡β_;≡2β) open _≡β_ import Declarative as Dec import Algorithmic as Alg import Algorithmic.Signature as Alg open import Type.BetaNormal using (_⊢Nf⋆_;_⊢Ne⋆_;embNf;embNe;ren-embNf;weakenNf;embNf-VecList;embNf-List;lookup-embNf-VecList) open _⊢Nf⋆_ open _⊢Ne⋆_ open import Type.BetaNBE using (nf;eval;idEnv) open import Type.BetaNBE.Completeness using (sub-eval;idCR;idext;reflectCR;fund) open import Type.BetaNBE.Soundness using (soundness) open import Type.BetaNBE.RenamingSubstitution using (_[_]Nf;subNf;subNf-cons;subNf∅;subNf∅≡subNf) open import Builtin using (Builtin) open import Type.BetaNBE.Stability open import Algorithmic.Completeness using (btype-lem)
embCtx : ∀{Φ} → Alg.Ctx Φ → Dec.Ctx Φ embCtx Alg.∅ = Dec.∅ embCtx (Γ Alg.,⋆ K) = embCtx Γ Dec.,⋆ K embCtx (Γ Alg., A) = embCtx Γ Dec., embNf A
embVar : ∀{Φ Γ}{A : Φ ⊢Nf⋆ *} → Γ Alg.∋ A → embCtx Γ Dec.∋ embNf A embVar Alg.Z = Dec.Z embVar (Alg.S α) = Dec.S (embVar α) embVar (Alg.T {A = A} α) = Dec.conv∋ refl (sym (ren-embNf S A)) (Dec.T (embVar α))
emb[] : ∀{Γ K}(A : Γ ⊢Nf⋆ K)(B : Γ ,⋆ K ⊢Nf⋆ *) → (embNf B [ embNf A ]) ≡β embNf (B [ A ]Nf) emb[] A B = trans≡β (soundness (embNf B [ embNf A ])) (≡2β (cong embNf (trans (trans (sub-eval (embNf B) idCR (sub-cons ` (embNf A))) (idext (λ { Z → idext idCR (embNf A) ; (S α) → reflectCR (refl {x = ` α})}) (embNf B))) (sym (sub-eval (embNf B) idCR (embNf ∘ subNf-cons (ne ∘ `) A))))))
soundness-μ : ∀{Φ Φ' K}(p : Φ ≡ Φ')(A : Φ ⊢Nf⋆ (K ⇒ *) ⇒ K ⇒ *)(B : Φ ⊢Nf⋆ K) → embNf A · ƛ (μ (weaken (embNf A)) (` Z)) · embNf B ≡β embNf (nf (embNf A · ƛ (μ (embNf (weakenNf A)) (` Z)) · embNf B)) soundness-μ p A B = trans≡β (soundness (embNf A · ƛ (μ (weaken (embNf A)) (` Z)) · embNf B)) (≡2β (cong (λ X → embNf (nf (embNf A · ƛ (μ X (` Z)) · embNf B))) (sym (ren-embNf S A))))
lemσ' : ∀{Γ Γ' Δ Δ'}(bn : Builtin)(p : Γ ≡ Γ') → (C : Δ ⊢⋆ *)(C' : Δ' ⊢Nf⋆ *) → (q : Δ ≡ Δ') → (σ : {J : Kind} → Δ' ∋⋆ J → Γ ⊢Nf⋆ J) → nf C ≡ substEq (_⊢Nf⋆ *) (sym q) C' → sub (λ {J} α → substEq (_⊢⋆ J) p (embNf (σ (substEq (_∋⋆ J) q α)))) C ≡β substEq (_⊢⋆ *) p (embNf (eval (sub (λ {J₁} x → embNf (σ x)) (embNf C')) (idEnv Γ))) lemσ' bn refl C C' refl σ p = trans≡β (soundness (sub (embNf ∘ σ) C)) (trans≡β (≡2β (cong embNf (sub-eval C idCR (embNf ∘ σ)))) (trans≡β (≡2β (cong embNf (fund (λ α → idext idCR (embNf (σ α))) (soundness C)))) (trans≡β (≡2β (sym (cong embNf (sub-eval (embNf (nf C)) idCR (embNf ∘ σ))))) (≡2β (cong embNf (cong nf (cong (sub (embNf ∘ σ)) (cong embNf p)))))))) _≡βL_ : ∀{Δ} → (As As' : List (Δ ⊢⋆ *)) → Set [] ≡βL [] = ⊤ [] ≡βL (A' ∷ As') = ⊥ (A ∷ As) ≡βL [] = ⊥ (A ∷ As) ≡βL (A' ∷ As') = (A ≡β A') × (As ≡βL As') refl≡βL : ∀{Δ} → (As : List (Δ ⊢⋆ *)) → As ≡βL As refl≡βL [] = tt refl≡βL (x ∷ As) = (refl≡β x) ,, (refl≡βL As) embList : ∀{Δ} → List (Δ ⊢Nf⋆ *) → List (Δ ⊢⋆ *) embList [] = [] embList (A ∷ As) = embNf A ∷ embList As lemsub : ∀{Γ Δ}(A : Δ ⊢Nf⋆ ♯)(A' : Δ ⊢⋆ ♯) → (σ : {J : Kind} → Δ ∋⋆ J → Γ ⊢Nf⋆ J) → embNf A ≡β A' → (embNf (subNf σ A)) ≡β sub (λ {J} α → embNf (σ α)) A' lemsub A A' σ p = trans≡β (trans≡β (≡2β (cong embNf (sub-eval (embNf A) idCR (embNf ∘ σ)))) (trans≡β (≡2β (cong embNf (fund (λ α → idext idCR (embNf (σ α))) p))) ((≡2β (sym (cong embNf (sub-eval A' idCR (embNf ∘ σ)))))))) (sym≡β (soundness (sub (embNf ∘ σ) A'))) subNf-sub∅-lem : ∀ Φ (A : ∅ ⊢Nf⋆ ♯) → embNf {Φ} (subNf (λ()) A) ≡β sub∅ (embNf A) subNf-sub∅-lem Φ A = trans≡β (lemsub A (embNf A) (λ {J} → λ()) (refl≡β (embNf A))) (≡2β (sub-cong (λ {()}) (embNf A))) subNf∅-sub∅-lem : ∀ Φ (A : ∅ ⊢Nf⋆ ♯) → embNf {Φ} (subNf∅ A) ≡β sub∅ (embNf A) subNf∅-sub∅-lem Φ A rewrite subNf∅≡subNf {Φ} {A = A} = subNf-sub∅-lem Φ A btype-lem≡β : ∀{Φ} b → Dec.btype {Φ} b ≡β embNf (Alg.btype b) btype-lem≡β {Φ} b rewrite btype-lem {Φ} b = soundness (Dec.btype {Φ} b) emb : ∀{Φ Γ}{A : Φ ⊢Nf⋆ *} → Γ Alg.⊢ A → embCtx Γ Dec.⊢ embNf A emb-ConstrArgs : ∀ {Φ} {Γ : Alg.Ctx Φ} {Ts : List (Φ ⊢Nf⋆ *)} (cs : Alg.ConstrArgs Γ Ts) → Dec.ConstrArgs (embCtx Γ) (embNf-List Ts) emb-ConstrArgs [] = [] emb-ConstrArgs (x ∷ cs) = (emb x) ∷ (emb-ConstrArgs cs) lema-mkCaseType : ∀{Φ}{A : Φ ⊢Nf⋆ *} As → embNf (Alg.mkCaseType A As) ≡ Dec.mkCaseType (embNf A) (embNf-List As) lema-mkCaseType [] = refl lema-mkCaseType (A ∷ As) = cong (embNf A ⇒_) (lema-mkCaseType As) emb-Cases : ∀ {Φ} {Γ : Alg.Ctx Φ} {A : Φ ⊢Nf⋆ *} {n} {Tss : Vec (List (Φ ⊢Nf⋆ *)) n} (cases : Alg.Cases Γ A Tss) → Dec.Cases (embCtx Γ) (embNf A) (embNf-VecList Tss) emb-Cases Alg.[] = Dec.[] emb-Cases (Alg._∷_ {Ts = Ts} c cases) = substEq (embCtx _ Dec.⊢_) (lema-mkCaseType Ts) (emb c) Dec.∷ (emb-Cases cases) emb (Alg.` α) = Dec.` (embVar α) emb (Alg.ƛ {A = A}{B} t) = Dec.ƛ (emb t) emb (Alg._·_ {A = A}{B} t u) = emb t Dec.· emb u emb (Alg.Λ {B = B} t) = Dec.Λ (emb t) emb (Alg._·⋆_/_ {B = B} t A refl) = Dec.conv (emb[] A B) (emb t Dec.·⋆ embNf A) emb (Alg.wrap A B t) = Dec.wrap (embNf A) (embNf B) (Dec.conv (sym≡β (soundness-μ refl A B)) (emb t)) emb (Alg.unwrap {A = A}{B} t refl) = Dec.conv (soundness-μ refl A B) (Dec.unwrap (emb t)) emb (Alg.con {A = A} t refl ) = Dec.con {A = embNf A} (substEq Alg.⟦_⟧ (sym (stability A)) t) (subNf∅-sub∅-lem _ A) emb (Alg.builtin b / refl) = Dec.conv (btype-lem≡β b) (Dec.builtin b) emb (Alg.error A) = Dec.error (embNf A) emb (Alg.constr e Tss refl cs) = Dec.constr e (embNf-VecList Tss) (sym (lookup-embNf-VecList e Tss)) (emb-ConstrArgs cs) emb (Alg.case x cases) = Dec.case (emb x) (emb-Cases cases) soundnessT : ∀{Φ Γ}{A : Φ ⊢Nf⋆ *} → Γ Alg.⊢ A → embCtx Γ Dec.⊢ embNf A soundnessT = emb