Tom de Jong & Martin Escardo, 20 May 2019.
Combinatory version of Platek-Scott-Plotkin PCF.
Includes (reflexive transitive closure of) operational semantics.
\begin{code}
{-# OPTIONS --safe --without-K #-}
open import UF.PropTrunc
module PCF.Combinatory.PCF (pt : propositional-truncations-exist) where
open PropositionalTruncation pt
open import MLTT.Spartan
open import UF.Subsingletons
data type : 𝓤₀ ̇ where
ι : type
_⇒_ : type → type → type
infixr 1 _⇒_
data PCF : (σ : type) → 𝓤₀ ̇ where
Zero : PCF ι
Succ : PCF (ι ⇒ ι)
Pred : PCF (ι ⇒ ι)
ifZero : PCF (ι ⇒ ι ⇒ ι ⇒ ι)
Fix : {σ : type} → PCF ((σ ⇒ σ) ⇒ σ)
K : {σ τ : type} → PCF (σ ⇒ τ ⇒ σ)
S : {ρ σ τ : type} → PCF ((ρ ⇒ σ ⇒ τ) ⇒ (ρ ⇒ σ) ⇒ ρ ⇒ τ)
_·_ : {σ τ : type} → PCF (σ ⇒ τ) → PCF σ → PCF τ
infixl 1 _·_
⌜_⌝ : ℕ → PCF ι
⌜ zero ⌝ = Zero
⌜ succ n ⌝ = Succ · ⌜ n ⌝
data _▹'_ : {σ : type} → PCF σ → PCF σ → 𝓤₀ ̇ where
Pred-zero : (Pred · Zero) ▹' Zero
Pred-succ : (n : ℕ) → (Pred · ⌜ succ n ⌝) ▹' ⌜ n ⌝
ifZero-zero : (s t : PCF ι) → (ifZero · s · t · Zero) ▹' s
ifZero-succ : (n : ℕ) (s t : PCF ι) → (ifZero · s · t · ⌜ succ n ⌝) ▹' t
Fix-step : {σ : type} (t : PCF (σ ⇒ σ)) → (Fix · t) ▹' (t · (Fix · t))
K-step : {σ τ : type} (s : PCF σ) (t : PCF τ) → (K · s · t) ▹' s
S-step : {ρ σ τ : type} (f : PCF (ρ ⇒ σ ⇒ τ)) (g : PCF (ρ ⇒ σ)) (x : PCF ρ) →
(S · f · g · x) ▹' (f · x · (g · x))
·-step : {σ τ : type} (s t : PCF (σ ⇒ τ)) (r : PCF σ) →
s ▹' t → (s · r) ▹' (t · r)
Pred-arg : (s t : PCF ι) → s ▹' t → (Pred · s) ▹' (Pred · t)
Succ-arg : (s t : PCF ι) → s ▹' t → (Succ · s) ▹' (Succ · t)
ifZero-arg : (s t r r' : PCF ι) →
r ▹' r' → (ifZero · s · t · r) ▹' (ifZero · s · t · r')
_▹_ : {σ : type} → PCF σ → PCF σ → 𝓤₀ ̇
s ▹ t = ∥ s ▹' t ∥
data _▹*'_ : {σ : type} → PCF σ → PCF σ → 𝓤₀ ̇ where
extend : {σ : type} {s t : PCF σ} → s ▹ t → s ▹*' t
refl : {σ : type} (s : PCF σ) → s ▹*' s
trans : {σ : type} {s t r : PCF σ} → s ▹*' t → t ▹*' r → s ▹*' r
_▹*_ : {σ : type} → PCF σ → PCF σ → 𝓤₀ ̇
s ▹* t = ∥ s ▹*' t ∥
▹'-to-▹*' : {σ τ : type} (f : PCF σ → PCF τ) →
((s t : PCF σ) → s ▹' t → (f s) ▹' (f t)) →
(s t : PCF σ) → s ▹*' t → (f s) ▹*' (f t)
▹'-to-▹*' f f-preserves-▹' s t (extend rel) = extend (∥∥-rec a b rel)
where
a : is-prop (f s ▹ f t)
a = ∥∥-is-prop
b : (step : s ▹' t) → ∥ f s ▹' f t ∥
b step = ∣ f-preserves-▹' s t step ∣
▹'-to-▹*' f f-preserves-▹' s s (refl s) = refl (f s)
▹'-to-▹*' f f-preserves-▹' s r (trans {σ} {s} {t} {r} rel₁ rel₂) = trans IH₁ IH₂
where
IH₁ : f s ▹*' f t
IH₁ = ▹'-to-▹*' f f-preserves-▹' s t rel₁
IH₂ : f t ▹*' f r
IH₂ = ▹'-to-▹*' f f-preserves-▹' t r rel₂
▹'-to-▹* : {σ τ : type} (f : PCF σ → PCF τ) →
((s t : PCF σ) → s ▹' t → (f s) ▹' (f t)) →
(s t : PCF σ) → s ▹* t → (f s) ▹* (f t)
▹'-to-▹* f f-preserves-▹' s t = ∥∥-functor (▹'-to-▹*' f f-preserves-▹' s t)
·-step* : {σ τ : type} (f g : PCF (σ ⇒ τ)) (t : PCF σ)
→ f ▹* g → (f · t) ▹* (g · t)
·-step* f g t rel = ▹'-to-▹* (λ x → x · t) (λ f' g' → ·-step f' g' t) f g rel
Succ-arg* : (s t : PCF ι) → s ▹* t → (Succ · s) ▹* (Succ · t)
Succ-arg* = ▹'-to-▹* (λ x → Succ · x) Succ-arg
Pred-arg* : (s t : PCF ι) → s ▹* t → (Pred · s) ▹* (Pred · t)
Pred-arg* = ▹'-to-▹* (λ x → Pred · x) Pred-arg
ifZero-arg* : (s t r r' : PCF ι) → r ▹* r'
→ (ifZero · s · t · r) ▹* (ifZero · s · t · r')
ifZero-arg* s t = ▹'-to-▹* (λ x → ifZero · s · t · x) (ifZero-arg s t)
\end{code}