{-# OPTIONS --without-K #-} module IK.Norm.Properties.Completeness where -- -- This module proves the soundness of evaluation (eval-sound), -- from which the completeness of normalization (norm-complete) follows. -- open import Data.Unit using (⊤ ; tt) open import Data.Product using (Σ ; _×_ ; _,_ ; ∃) open import Relation.Binary.PropositionalEquality open import IK.Norm.Base open import IK.Norm.NbE.Model open import IK.Norm.NbE.Reification open import IK.Term -- soundness relation on semantic values _≋_ : Tm' Γ a → Tm' Γ a → Set _≋_ {Γ} {a = ι} n m = n ≡ m _≋_ {Γ} {a = a ⇒ b} f g = {Γ' : Ctx} (w : Γ ⊆ Γ') → {x y : Tm' Γ' a} → Psh x → Psh y → x ≋ y → f w x ≋ g w y _≋_ {Γ} {a = □ a} b c = let box' x = b ; box' y = c in x ≋ y -- soundness relation on semantic substitutions data _≋ₛ_ : Sub' Γ Δ → Sub' Γ Δ → Set where [] : _≋ₛ_ {Γ = Γ} {Δ = []} tt tt _`,_ : {s : Sub' Γ Δ} {s' : Sub' Γ Δ} {x : Tm' Γ a} {y : Tm' Γ a} → s ≋ₛ s' → x ≋ y → (s , x) ≋ₛ (s' , y) lock : {s : Sub' Γ Δ} {s' : Sub' Γ Δ} → s ≋ₛ s' → (e : LFExt Γ' (Γ #) (ΓR)) → _≋ₛ_ {Γ = Γ'} {Δ = Δ #} (lock s e) (lock s' e) ------------------------ -- Properties of ≋ and ≋ₛ ------------------------ -- ≋ is symmetric sym-≋ : {x y : Tm' Γ a} → x ≋ y → y ≋ x sym-≋ {a = ι} n≡m = sym n≡m sym-≋ {a = a ⇒ b} f≋g = λ w px' py' x'≋y' → sym-≋ {a = b} (f≋g w py' px' (sym-≋ {a = a} x'≋y')) sym-≋ {a = □ a} b≋c = sym-≋ {a = a} b≋c -- ≋ is transitive trans-≋ : {x y z : Tm' Γ a} → x ≋ y → y ≋ z → x ≋ z trans-≋ {a = ι} n≡m m≡o = trans n≡m m≡o trans-≋ {a = a ⇒ b} {f} {g} {h} f≋g g≋h w {x = x} {y = y} px py x≋y = trans-≋ {a = b} (f≋g w px py x≋y) (g≋h w py py ((trans-≋ {a = a} (sym-≋ {a = a} x≋y) x≋y))) trans-≋ {a = □ a} b≋c c≋d = trans-≋ {a = a} b≋c c≋d -- WTH should this thing be called? pseudo-refl-≋ : {x y : Tm' Γ a} → x ≋ y → x ≋ x pseudo-refl-≋ {a = a} x≋y = trans-≋ {a = a} x≋y (sym-≋ {a = a} x≋y) -- ≋ₛ is symmetric sym-≋ₛ : {s s' : Sub' Γ Δ} → s ≋ₛ s' → s' ≋ₛ s sym-≋ₛ {Δ = []} s≋s' = s≋s' sym-≋ₛ {Δ = Δ `, a} (s≋s' `, x≋y) = sym-≋ₛ s≋s' `, sym-≋ {a = a} x≋y sym-≋ₛ {Δ = Δ #} (lock s≋s' e) = lock (sym-≋ₛ s≋s') e -- ≋ₛ is transitive trans-≋ₛ : {s s' s'' : Sub' Γ Δ} → s ≋ₛ s' → s' ≋ₛ s'' → s ≋ₛ s'' trans-≋ₛ {Δ = []} s≋s' s'≋s'' = [] trans-≋ₛ {Δ = Δ `, a} (s≋s' `, x≋x') (s'≋s'' `, x'≋x'') = trans-≋ₛ s≋s' s'≋s'' `, trans-≋ {a = a} x≋x' x'≋x'' trans-≋ₛ {Δ = Δ #} (lock s≋s' e) (lock s'≋s'' e) = lock (trans-≋ₛ s≋s' s'≋s'') e -- WTH should this thing be called? pseudo-refl-≋ₛ : {s s' : Sub' Γ Δ} → s ≋ₛ s' → s ≋ₛ s pseudo-refl-≋ₛ x≋y = trans-≋ₛ x≋y (sym-≋ₛ x≋y) -- wkTm' preserves the relation _≋_ wkTm'Pres≋ : {x : Tm' Γ a} {y : Tm' Γ a} → (w : Γ ⊆ Δ) → x ≋ y → wkTm' w x ≋ wkTm' w y wkTm'Pres≋ {a = ι} w n≡m = cong (wkNf w) n≡m wkTm'Pres≋ {a = a ⇒ b} {x = f} {y = g} w f≋g = λ w' px py x≋y → f≋g (w ∙ w') px py x≋y wkTm'Pres≋ {a = □ a} w b≋c = wkTm'Pres≋ {a = a} (keep# w) b≋c -- wkSub' preserves the relation _≋_ wkSub'Pres≋ : {s s' : Sub' Γ Δ} → (w : Γ ⊆ Γ') → s ≋ₛ s' → wkSub' w s ≋ₛ wkSub' w s' wkSub'Pres≋ w [] = [] wkSub'Pres≋ {Δ = Δ `, a} w (s≋s' `, x) = wkSub'Pres≋ w s≋s' `, wkTm'Pres≋ {a = a} w x wkSub'Pres≋ w (lock s≋s e) = lock (wkSub'Pres≋ (sliceLeft e w) s≋s) (wkLFExt e w) -------------------------------------- -- The Fundamental theorem of ≋ and ≋ₛ -------------------------------------- private substVar'Pres≋ : (x : Var Γ a) {s s' : Sub' Δ Γ} → s ≋ₛ s' → substVar' x s ≋ substVar' x s' substVar'Pres≋ zero {s = _ , x} {s' = _ , y} (_ `, x≋y) = x≋y substVar'Pres≋ (succ x) {s = s , _} {s' = s' , _} (s≋s' `, _) = substVar'Pres≋ x s≋s' unbox'Pres≋ : {b c : Box (Tm'- a) Γ} → (e : LFExt Γ' (Γ #) ΓR) → b ≋ c → unbox' b e ≋ unbox' c e unbox'Pres≋ {a = a} e b≋c = wkTm'Pres≋ {a = a} (LFExtToWk e) b≋c -- fund : (t : Tm Γ a) {s s' : Sub' Δ Γ} → Pshₛ s → Pshₛ s' → s ≋ₛ s' → eval t s ≋ eval t s' fund (var x) ps ps' s≋s' = substVar'Pres≋ x s≋s' fund (lam t) {s = s} {s' = s'} ps ps' s≋s' w px py x≋y = fund t (wkSub'PresPsh w s ps , px) (wkSub'PresPsh w s' ps' , py) (wkSub'Pres≋ w s≋s' `, x≋y) fund (app t u) {s = s} {s' = s'} ps ps' s≋s' = fund t ps ps' s≋s' idWk (psh-eval u s ps) (psh-eval u s' ps') (fund u ps ps' s≋s') fund (box t) ps ps' s≋s' = fund t ps ps' (lock s≋s' nil) fund (unbox t nil) {s = lock s e} {s' = lock s' .e} ps ps' (lock s≋s' .e) = unbox'Pres≋ {b = eval t s} e (fund t ps ps' s≋s') fund (unbox t (ext e)) (ps , _) (ps' , _) (s≋s' `, _) = fund (unbox t e) ps ps' s≋s' -- fundₛ : (s₀ : Sub Γ Δ) {s s' : Sub' Δ' Γ} → Pshₛ s → Pshₛ s' → s ≋ₛ s' → evalₛ s₀ s ≋ₛ evalₛ s₀ s' fundₛ [] ps ps' s≋s' = [] fundₛ (s₀ `, t) ps ps' s≋s' = (fundₛ s₀ ps ps' s≋s') `, fund t ps ps' s≋s' fundₛ (lock s₀ (ext e)) {s = s , _} {s' = s' , _} (ps , _) (ps' , _) (s≋s' `, _) = fundₛ (lock s₀ e) ps ps' s≋s' fundₛ (lock s₀ nil) {s = lock s e} {s' = lock s' e} ps ps' (lock s≋s' e) = lock (fundₛ s₀ ps ps' s≋s') e -------------------------- -- Soundness of evaluation -------------------------- coh-substVar-evalₛ : (x : Var Γ a) (s₀ : Sub Δ Γ) {s s' : Sub' Δ' Δ} → Pshₛ s → Pshₛ s' → s ≋ₛ s' → substVar' x (evalₛ s₀ s') ≋ eval (substVar s₀ x) s' coh-substVar-evalₛ zero (_ `, t) {s} {s'} ps ps' s≋s' = pseudo-refl-≋ {x = eval t s'} (sym-≋ {x = eval t s} (fund t ps ps' s≋s')) coh-substVar-evalₛ (succ x) (s₀ `, _) ps ps' s≋s' = coh-substVar-evalₛ x s₀ ps ps' s≋s' coh-substTm-evalₛ : (t : Tm Γ a) (s₀ : Sub Δ Γ) {s s' : Sub' Δ' Δ} → Pshₛ s → Pshₛ s' → s ≋ₛ s' → eval t (evalₛ s₀ s') ≋ eval (substTm s₀ t) s' coh-substTm-evalₛ (var x) s₀ ps ps' s≋s' = coh-substVar-evalₛ x s₀ ps ps' s≋s' coh-substTm-evalₛ (lam t) s₀ {s} {s'} ps ps' s≋s' w {x = x} {y} px py x≋y rewrite sym (nat-evalₛ w s₀ s' ps') = trans-≋ {z = eval (substTm (wkSub fresh s₀ `, var zero) t) (wkSub' w s' , y)} ((subst (λ z → _ ≋ eval t (z , y)) (trans (cong (evalₛ s₀) (sym (trimSub'PresId _))) (sym (coh-trimSub'-wkSub fresh s₀ (wkSub' w s' , y)))) (fund t (psh-evalₛ s₀ _ (wkSub'PresPsh w s' ps') , px) (psh-evalₛ s₀ _ (wkSub'PresPsh w s' ps') , py) (fundₛ s₀ (wkSub'PresPsh w s' ps') (wkSub'PresPsh w s' ps') (wkSub'Pres≋ w ((pseudo-refl-≋ₛ {s = s'} (sym-≋ₛ s≋s')))) `, x≋y)))) ((coh-substTm-evalₛ t (keepₛ s₀) (wkSub'PresPsh w s ps , px) (wkSub'PresPsh w s' ps' , py) (wkSub'Pres≋ w s≋s' `, x≋y))) coh-substTm-evalₛ (app t u) s₀ ps ps' s≋s' = coh-substTm-evalₛ t s₀ ps ps' s≋s' idWk (psh-eval u _ (psh-evalₛ s₀ _ ps')) (psh-eval (substTm s₀ u) _ ps') (coh-substTm-evalₛ u s₀ ps ps' s≋s') coh-substTm-evalₛ (box t) s₀ ps ps' s≋s' = coh-substTm-evalₛ t (lock s₀ nil) ps ps' (lock s≋s' nil) coh-substTm-evalₛ (unbox t (ext e)) (s₀ `, _) ps ps' s≋s' = coh-substTm-evalₛ (unbox t e) s₀ ps ps' s≋s' coh-substTm-evalₛ (unbox t nil) (lock s₀ (ext e)) (ps , _) (ps' , _) (s≋s' `, _) = coh-substTm-evalₛ (unbox t nil) (lock s₀ e) ps ps' s≋s' coh-substTm-evalₛ (unbox t nil) (lock s₀ nil) {s = lock s e} {s' = lock s' e'} ps ps' (lock s≋s' e') = unbox'Pres≋ {b = eval t (evalₛ s₀ s')} e' (coh-substTm-evalₛ t s₀ ps ps' s≋s') private lemma1 : {t : Tm (ΓL #) a} (e : LFExt Γ (ΓL #) ΓR) {s s' : Sub' Δ Γ} → Pshₛ s → Pshₛ s' → s ≋ₛ s' → eval (unbox (box t) e) s ≋ eval t (trimSub' (LFExtToWk e) s') lemma1 {t = t} nil {s = lock s e} {s' = lock s' e} ps ps' (lock s≋s' e) with ←#IsPre# e | #→IsPost# e ... | refl | refl rewrite sym (nat-eval t (LFExtToWk e) (lock s nil) ps) | ExtIsProp (wkLFExt nil (LFExtToWk e)) e = fund t (wkSub'PresPsh (sliceLeft nil (LFExtToWk e)) s ps) (subst Pshₛ (sym (trimSub'PresId s')) ps') (lock lemma1-2 e) where lemma1-1' : ∀ (e : LFExt Γ ΓL ΓR) → (p : ΓL ≡ ←# Γ #) → sliceLeft nil (LFExtToWk (subst (λ ΓL → LFExt Γ ΓL ΓR) p e)) ≡ idWk lemma1-1' {Γ = Γ #} nil p rewrite Ctx-K p = refl lemma1-1' {Γ = Γ `, a} (ext e) refl = lemma1-1' e refl lemma1-1 : ∀ (e : LFExt Γ (←# Γ #) ΓR) → sliceLeft nil (LFExtToWk e) ≡ idWk lemma1-1 e = lemma1-1' e refl lemma1-2 : wkSub' (sliceLeft nil (LFExtToWk e)) s ≋ₛ trimSub' idWk s' lemma1-2 rewrite lemma1-1 e | trimSub'PresId s' | wkSub'PresId s = s≋s' lemma1 {t = t} (ext e) (s , _) (s' , _) (s≋s' `, _) = lemma1 {t = t} e s s' s≋s' lemma2 : {b c : Tm' Γ (□ a)} → b ≋ c → b ≋ box' (unbox' c new) lemma2 {c = c} b≋c rewrite (let box' y = c in wkTm'PresId y) = b≋c -- soundness of evaluation wrt single-step reduction eval-sound-red : {t t' : Tm Γ a} {s s' : Sub' Δ Γ} → t ⟶ t' → Pshₛ s → Pshₛ s' → s ≋ₛ s' → eval t s ≋ eval t' s' eval-sound-red {Γ = Γ} {Δ = Δ} {t = app (lam {b = b} t) u} {s = s} {s' = s'} red-fun ps ps' s≋s' rewrite wkSub'PresId s | evalₛPresId s' = trans-≋ {Γ = Δ} {a = b} (fund t (ps , (psh-eval u s ps)) (subst Pshₛ (sym (evalₛPresId s')) ps' , psh-eval u s' ps') (subst (s ≋ₛ_) (sym (evalₛPresId s')) s≋s' `, fund u ps ps' s≋s')) (coh-substTm-evalₛ t (idₛ `, u) {s} {s'} ps ps' s≋s') eval-sound-red {t = t} {s = s} {s'} exp-fun ps ps' s≋s' w {x = x} px py x≋y rewrite sym (rightIdWk w) | sym (cong (λ f → f idWk x) (nat-eval t w s ps)) | sym (trimSub'PresId (wkSub' w s)) | rightIdWk w | sym (coh-trimSub'-wkTm fresh (wkSub' w s , x) t) = fund (wkTm (drop idWk) t) (wkSub'PresPsh w s ps , px) (wkSub'PresPsh w s' ps' , py) (wkSub'Pres≋ w s≋s' `, x≋y) idWk px py x≋y eval-sound-red {t = unbox (box t) e} {s = s} {s' = s'} red-box ps ps' s≋s' rewrite coh-trimSub'-wkTm (LFExtToWk e) s' t = lemma1 {t = t} e ps ps' s≋s' eval-sound-red {t = t} {s = s} {s'} exp-box ps ps' s≋s' = lemma2 {b = eval t s} (fund t ps ps' s≋s') eval-sound-red {t = t} {s = s} {s'} (cong-lam r) ps ps' s≋s' w {x = x} px py x≋y = eval-sound-red r (wkSub'PresPsh w s ps , px) (wkSub'PresPsh w s' ps' , py) ((wkSub'Pres≋ w s≋s') `, x≋y) eval-sound-red {t = app t u} {t' = app t' u'} {s = s} {s' = s'} (cong-app1 r) ps ps' s≋s' = eval-sound-red r ps ps' s≋s' idWk (psh-eval u s ps) (psh-eval u s' ps') (fund u ps ps' s≋s') eval-sound-red {t = app t u} {t' = app t' u'} {s = s} {s' = s'} (cong-app2 r) ps ps' s≋s' = fund t ps ps' s≋s' idWk (psh-eval u s ps) (psh-eval u' s' ps') (eval-sound-red r ps ps' s≋s') eval-sound-red (cong-box r) ps ps' s≋s' = eval-sound-red r ps ps' (lock s≋s' nil) eval-sound-red {s = lock s e} {s' = lock s' .e} (cong-unbox {t = t} {e = nil} r) ps ps' (lock s≋s' e) = unbox'Pres≋ {b = eval t s} e (eval-sound-red r ps ps' s≋s') eval-sound-red {s = s , _} {s' = s' , _} (cong-unbox {t = t} {e = ext e} r) (ps , _) (ps' , _) (s≋s' `, _) = eval-sound-red (cong-unbox {e = e} r) ps ps' s≋s' -- soundness of evaluation wrt multi-step reduction eval-sound-red* : {t t' : Tm Γ a} {s s' : Sub' Δ Γ} → t ⟶* t' → Pshₛ s → Pshₛ s' → s ≋ₛ s' → eval t s ≋ eval t' s' eval-sound-red* {t = t} {t' = .t} ε ps ps' s≋s' = fund t ps ps' s≋s' eval-sound-red* {a = a} {t = t} {t' = t'} (r ◅ rs) ps ps' s≋s' = trans-≋ {a = a} (eval-sound-red r ps ps' s≋s') (eval-sound-red* rs ps' ps' (pseudo-refl-≋ₛ (sym-≋ₛ s≋s'))) -- soundness of evaluation wrt conversion eval-sound : {t t' : Tm Γ a} {s s' : Sub' Δ Γ} → t ≈ t' → Pshₛ s → Pshₛ s' → s ≋ₛ s' → eval t s ≋ eval t' s' eval-sound {t = t} ε ps ps' s≋s' = eval-sound-red* {t = t} ⟶*-refl ps ps' s≋s' eval-sound {a = a} (inj₁ r ◅ t≈t') ps ps' s≋s' = trans-≋ {a = a} (eval-sound-red r ps ps' s≋s') (eval-sound t≈t' ps' ps' (pseudo-refl-≋ₛ (sym-≋ₛ s≋s'))) eval-sound {a = a} {t = t} {s = s} {s' = s'} (inj₂ r ◅ t≈t') ps ps' s≋s' = trans-≋ {a = a} (sym-≋ {y = eval t s} (eval-sound-red r ps' ps (sym-≋ₛ s≋s'))) (eval-sound t≈t' ps' ps' (pseudo-refl-≋ₛ (sym-≋ₛ s≋s'))) -------------------------------------------------------- -- Uniqueness of reification and soundness of reflection -------------------------------------------------------- unique-reify : {x y : Tm' Γ a} → x ≋ y → reify x ≡ reify y sound-reflect : {n n' : Ne Γ a} → n ≡ n' → reflect n ≋ reflect n' unique-reify {a = ι} n≡m = n≡m unique-reify {a = a ⇒ b} f≋g = cong lam (unique-reify (f≋g fresh (psh-reflect {a = a} (var zero)) (psh-reflect {a = a} (var zero)) (sound-reflect {a = a} refl))) unique-reify {a = □ a} b≋c = cong box (unique-reify b≋c) sound-reflect {a = ι} n≡n' = cong up n≡n' sound-reflect {a = a ⇒ b} n≡n' w px py x≋y = sound-reflect {a = b} (cong₂ app (cong (wkNe w) n≡n') (unique-reify x≋y)) sound-reflect {a = □ a} n≡n' = sound-reflect {a = a} (cong₂ unbox n≡n' refl) -------------------------------- -- Completeness of normalization -------------------------------- idₛ'≋idₛ' : {Γ : Ctx} → idₛ' {Γ} ≋ₛ idₛ' idₛ'≋idₛ' {[]} = [] idₛ'≋idₛ' {Γ `, a} = (wkSub'Pres≋ fresh (idₛ'≋idₛ' {Γ})) `, (sound-reflect {a = a} refl) idₛ'≋idₛ' {Γ #} = lock idₛ'≋idₛ' nil norm-complete-red* : {t t' : Tm Γ a} → t ⟶* t' → norm t ≡ norm t' norm-complete-red* {Γ = Γ} r = unique-reify (eval-sound-red* r (psh-idₛ' {Γ}) (psh-idₛ' {Γ}) idₛ'≋idₛ') norm-complete : {t t' : Tm Γ a} → t ≈ t' → norm t ≡ norm t' norm-complete {Γ = Γ} p = unique-reify (eval-sound p (psh-idₛ' {Γ}) (psh-idₛ' {Γ}) idₛ'≋idₛ')
Generated from commit 2fd14c996b195ef101dff8919e837907ca0a08aa.