Brendan Hart 2019-2020
\begin{code}
{-# OPTIONS --safe --without-K --lossy-unification #-}
open import MLTT.Spartan
open import UF.FunExt
open import UF.PropTrunc
open import UF.Subsingletons
module PCF.Lambda.SubstitutionDenotational
(pt : propositional-truncations-exist)
(fe : ∀ {𝓤 𝓥} → funext 𝓤 𝓥)
(pe : propext 𝓤₀)
where
open PropositionalTruncation pt
open import DomainTheory.Basics.Dcpo pt fe 𝓤₀
open import DomainTheory.Basics.LeastFixedPoint pt fe 𝓤₀
open import DomainTheory.Basics.Pointed pt fe 𝓤₀
open import DomainTheory.Basics.Products pt fe
open import Lifting.Monad 𝓤₀ hiding (μ)
open import Naturals.Properties
open import PCF.Combinatory.PCFCombinators pt fe 𝓤₀
open import PCF.Lambda.AbstractSyntax pt
open import PCF.Lambda.ScottModelOfContexts pt fe pe
open import PCF.Lambda.ScottModelOfTerms pt fe pe
open import PCF.Lambda.ScottModelOfTypes pt fe pe
open import UF.Base
open DcpoProductsGeneral 𝓤₀
open IfZeroDenotationalSemantics pe
replace-first-lemma : {n : ℕ} {Γ : Context n} {σ τ : type}
(x : (Γ ’ τ) ∋ σ)
(d : ⟨ (【 Γ 】 ⁻) ⟩)
(T : PCF Γ τ)
→ (pr₁ ⟦ v x ⟧ₑ (d , pr₁ ⟦ T ⟧ₑ d))
= pr₁ ⟦ replace-first τ Γ T x ⟧ₑ d
replace-first-lemma {n} {Γ} {σ} {.σ} Z d T = refl
replace-first-lemma {n} {Γ} {σ} {τ} (S x) d T = refl
extract-S-lemma : {n : ℕ}
{Γ : Context n}
{σ : type}
(d : ⟨ (【 Γ 】 ⁻) ⟩)
(e : ⟨ (⟦ σ ⟧ ⁻) ⟩)
{A : type}
(x : Γ ∋ A)
→ extract x d = extract (S {n} {Γ} {A} {σ} x) (d , e)
extract-S-lemma d e Z = refl
extract-S-lemma d e (S x) = refl
rename-lemma : {n m : ℕ}
{Γ : Context n} {Δ : Context m}
{σ : type}
(M : PCF Γ σ)
(ρ : ∀ {A} → Γ ∋ A → Δ ∋ A)
(d : ⟨ (【 Δ 】 ⁻) ⟩)
(e : ⟨ (【 Γ 】 ⁻) ⟩)
→ ({A : type} (x : Γ ∋ A) → extract x e = extract (ρ x) d)
→ pr₁ ⟦ rename ρ M ⟧ₑ d = pr₁ ⟦ M ⟧ₑ e
rename-lemma Zero ρ d e eq = refl
rename-lemma (Succ M) ρ d e eq = ap (𝓛̇ succ) (rename-lemma M ρ d e eq)
rename-lemma (Pred M) ρ d e eq = ap (𝓛̇ pred) (rename-lemma M ρ d e eq)
rename-lemma (IfZero M M₁ M₂) ρ d e eq =
ap₃
(λ x₁ x₂ x₃ → pr₁ (⦅ifZero⦆₁ x₂ x₃) x₁)
(rename-lemma M ρ d e eq)
(rename-lemma M₁ ρ d e eq) (rename-lemma M₂ ρ d e eq)
rename-lemma (ƛ {n} {Γ} {σ} {τ} M) ρ d e eq = γ
where
IH : (λ z → pr₁ ⟦ rename (ext ρ) M ⟧ₑ (d , z)) ∼ (λ z → pr₁ ⟦ M ⟧ₑ (e , z))
IH z = rename-lemma M (ext ρ) (d , z) (e , z) g
where
g : ∀ {A} → (x : (Γ ’ σ) ∋ A) → extract x (e , z) = extract (ext ρ x) (d , z)
g Z = refl
g (S x) = eq x
γ : pr₁ ⟦ rename ρ (ƛ M) ⟧ₑ d = pr₁ ⟦ ƛ M ⟧ₑ e
γ = to-subtype-= (being-continuous-is-prop (⟦ σ ⟧ ⁻) (⟦ τ ⟧ ⁻)) (dfunext fe IH)
rename-lemma (M · M₁) ρ d e eq =
ap₂
pr₁
(rename-lemma M ρ d e eq)
(rename-lemma M₁ ρ d e eq)
rename-lemma (v x) ρ d e eq = eq x ⁻¹
rename-lemma (Fix {_} {_} {σ} M) ρ d e eq =
ap
(pr₁ (μ ⟦ σ ⟧))
(rename-lemma M ρ d e eq)
substitution-lemma : {n : ℕ}{Γ : Context n}
{m : ℕ}{Δ : Context m}
{σ : type}
(M : PCF Γ σ)
(f : ∀ {A} → Γ ∋ A → PCF Δ A)
(e : ⟨ (【 Γ 】 ⁻) ⟩)
(d : ⟨ (【 Δ 】 ⁻) ⟩)
(g : ∀ {A} → (x : Γ ∋ A) → pr₁ ⟦ v x ⟧ₑ e = pr₁ ⟦ f x ⟧ₑ d )
→ pr₁ ⟦ M ⟧ₑ e = pr₁ ⟦ subst f M ⟧ₑ d
substitution-lemma Zero f e d g = refl
substitution-lemma (Succ M) f e d g = ap (𝓛̇ succ) (substitution-lemma M f e d g)
substitution-lemma (Pred M) f e d g = ap (𝓛̇ pred) (substitution-lemma M f e d g)
substitution-lemma (IfZero M M₁ M₂) f e d g =
pr₁ (⦅ifZero⦆₁ (pr₁ ⟦ M₁ ⟧ₑ e) (pr₁ ⟦ M₂ ⟧ₑ e)) (pr₁ ⟦ M ⟧ₑ e) =⟨ i ⟩
pr₁ (⦅ifZero⦆₁ (pr₁ ⟦ M₁ ⟧ₑ e) (pr₁ ⟦ M₂ ⟧ₑ e)) (pr₁ ⟦ subst f M ⟧ₑ d) =⟨ ii ⟩
pr₁ (⦅ifZero⦆₁ (pr₁ ⟦ subst f M₁ ⟧ₑ d) (pr₁ ⟦ M₂ ⟧ₑ e)) (pr₁ ⟦ subst f M ⟧ₑ d) =⟨ iii ⟩
pr₁ (⦅ifZero⦆₁ (pr₁ ⟦ subst f M₁ ⟧ₑ d) (pr₁ ⟦ subst f M₂ ⟧ₑ d)) (pr₁ ⟦ subst f M ⟧ₑ d) ∎
where
i = ap
(pr₁ (⦅ifZero⦆₁ (pr₁ ⟦ M₁ ⟧ₑ e) (pr₁ ⟦ M₂ ⟧ₑ e)))
(substitution-lemma M f e d g)
ii = ap
(λ - → pr₁ (⦅ifZero⦆₁ - (pr₁ ⟦ M₂ ⟧ₑ e)) (pr₁ ⟦ subst f M ⟧ₑ d))
(substitution-lemma M₁ f e d g)
iii = ap
(λ - → pr₁ (⦅ifZero⦆₁ (pr₁ ⟦ subst f M₁ ⟧ₑ d) -) (pr₁ ⟦ subst f M ⟧ₑ d))
(substitution-lemma M₂ f e d g)
substitution-lemma {_} {_} {m} {Δ} (ƛ {n} {Γ} {σ} {τ} M) f e d g = e₂
where
e₁ : (pr₁ (pr₁ ⟦ ƛ M ⟧ₑ e)) ∼ (pr₁ (pr₁ ⟦ subst f (ƛ M) ⟧ₑ d))
e₁ x = substitution-lemma M (exts f) (e , x) (d , x) new_g
where
new_g : {A : type}
(z : (Γ ’ σ) ∋ A)
→ pr₁ ⟦ v z ⟧ₑ (e , x) = pr₁ ⟦ exts f z ⟧ₑ (d , x)
new_g Z = refl
new_g {A} (S z) =
pr₁ ⟦ v (S {n} {Γ} {A} {σ} z) ⟧ₑ (e , x) =⟨ refl ⟩
pr₁ ⟦ v z ⟧ₑ e =⟨ g z ⟩
pr₁ ⟦ f z ⟧ₑ d =⟨ i ⟩
pr₁ ⟦ exts f (S z) ⟧ₑ (d , x) ∎
where
i = (rename-lemma (f z) S (d , x) d (λ x₁ → refl)) ⁻¹
e₂ : pr₁ ⟦ ƛ M ⟧ₑ e = pr₁ ⟦ subst f (ƛ M) ⟧ₑ d
e₂ = to-subtype-=
(being-continuous-is-prop (⟦ σ ⟧ ⁻) (⟦ τ ⟧ ⁻))
(dfunext fe e₁)
substitution-lemma (M · M₁) f e d g = γ
where
IH₁ : pr₁ ⟦ M₁ ⟧ₑ e = pr₁ ⟦ subst f M₁ ⟧ₑ d
IH₁ = substitution-lemma M₁ f e d g
IH : pr₁ ⟦ M ⟧ₑ e = pr₁ ⟦ subst f M ⟧ₑ d
IH = substitution-lemma M f e d g
γ = pr₁ (pr₁ ⟦ M ⟧ₑ e) (pr₁ ⟦ M₁ ⟧ₑ e) =⟨ i ⟩
pr₁ (pr₁ ⟦ M ⟧ₑ e) (pr₁ ⟦ subst f M₁ ⟧ₑ d) =⟨ ii ⟩
pr₁ (pr₁ ⟦ subst (λ {A} → f) M ⟧ₑ d) (pr₁ ⟦ subst (λ {A} → f) M₁ ⟧ₑ d) ∎
where
i = ap (pr₁ (pr₁ ⟦ M ⟧ₑ e)) IH₁
ii = ap (λ - → pr₁ - (pr₁ ⟦ subst f M₁ ⟧ₑ d)) IH
substitution-lemma {n} {Γ} {m} {Δ} (v x) f e d g = g x
substitution-lemma {n} {Γ} {m} {Δ} {σ} (Fix M) f e d g =
ap
(λ - → pr₁ (μ ⟦ σ ⟧ ) -)
(substitution-lemma M f e d g)
β-equality : {n : ℕ}
{Γ : Context n}
{σ τ : type}
(E : PCF (Γ ’ τ) σ)
(T : PCF Γ τ)
(d : ⟨ (【 Γ 】 ⁻) ⟩)
→ pr₁ ⟦ (ƛ E) · T ⟧ₑ d = pr₁ ⟦ E [ T ] ⟧ₑ d
β-equality {n} {Γ} {σ} {τ} E T d =
substitution-lemma E (replace-first τ Γ T) (d , (pr₁ ⟦ T ⟧ₑ d)) d g
where
g : {A : type}
(x : (Γ ’ τ) ∋ A)
→ pr₁ ⟦ v x ⟧ₑ (d , pr₁ ⟦ T ⟧ₑ d) = pr₁ ⟦ replace-first τ Γ T x ⟧ₑ d
g Z = refl
g (S x) = refl
\end{code}