Brendan Hart 2019-2020
\begin{code}
{-# OPTIONS --safe --without-K #-}
open import MLTT.Spartan
open import UF.PropTrunc
module PCF.Lambda.ApplicativeApproximation
(pt : propositional-truncations-exist)
where
open PropositionalTruncation pt
open import PCF.Lambda.AbstractSyntax pt
open import PCF.Lambda.BigStep pt
_⊏̰_ : {σ : type} → PCF ⟨⟩ σ → PCF ⟨⟩ σ → 𝓤₀ ̇
_⊏̰_ {ι} M N = (n : ℕ) → M ⇓ numeral n → N ⇓ numeral n
_⊏̰_ {σ ⇒ σ₁} M N = (P : PCF ⟨⟩ σ) → (M · P) ⊏̰ (N · P)
⊏̰-reflexive : {σ : type} → (M : PCF ⟨⟩ σ) → M ⊏̰ M
⊏̰-reflexive {ι} M = λ n x → x
⊏̰-reflexive {σ ⇒ σ₁} M = λ P → ⊏̰-reflexive (M · P)
⊏̰-transitive : {σ : type} {M N L : PCF ⟨⟩ σ} → M ⊏̰ N → N ⊏̰ L → M ⊏̰ L
⊏̰-transitive {ι} {M} {N} {L} p₁ p₂ n step = γ
where
γ : L ⇓ numeral n
γ = p₂ n (p₁ n step)
⊏̰-transitive {σ ⇒ σ₁} {M} {N} {L} p₁ p₂ P = γ
where
γ : (M · P) ⊏̰ (L · P)
γ = ⊏̰-transitive (p₁ P) (p₂ P)
⊏̰-lemma : {σ : type} (M M' : PCF ⟨⟩ σ)
→ ((V : PCF ⟨⟩ σ) → M ⇓' V → M' ⇓' V)
→ M ⊏̰ M'
⊏̰-lemma {ι} M M' f n x = ∥∥-functor (λ x₁ → f (numeral n) x₁) x
⊏̰-lemma {σ ⇒ τ} M M' f P = ⊏̰-lemma (M · P) (M' · P) γ
where
γ : (V : PCF ⟨⟩ τ) → (M · P) ⇓' V → (M' · P) ⇓' V
γ V (·-step {_} {_} {_} {_} {_} {E} x x₁) = ·-step M'-step x₁
where
M'-step : M' ⇓' ƛ E
M'-step = f (ƛ E) x
β-⊏̰ : {σ τ : type} {M : PCF (⟨⟩ ’ σ) τ} {N : PCF ⟨⟩ σ}
→ (M [ N ]) ⊏̰ (ƛ M · N)
β-⊏̰ {σ} {τ} {M} {N} = ⊏̰-lemma (M [ N ]) (ƛ M · N) (λ V x → ·-step ƛ-id x)
fix-⊏̰ : {σ : type} {M : PCF ⟨⟩ (σ ⇒ σ)} → (M · (Fix M)) ⊏̰ (Fix M)
fix-⊏̰ {σ} {M} = ⊏̰-lemma (M · Fix M) (Fix M) (λ V x → Fix-step x)
\end{code}