Brendan Hart 2019-2020

\begin{code}

{-# OPTIONS --safe --without-K #-}

open import MLTT.Spartan
open import UF.FunExt
open import UF.PropTrunc
open import UF.Subsingletons

module PCF.Lambda.Adequacy
        (pt : propositional-truncations-exist)
        (fe :  {𝓤 𝓥}  funext 𝓤 𝓥)
        (pe : propext 𝓤₀)
       where

open PropositionalTruncation pt

open import UF.UniverseEmbedding
open import DomainTheory.Basics.Dcpo pt fe 𝓤₀
open import DomainTheory.Basics.Exponential pt fe 𝓤₀
open import DomainTheory.Basics.LeastFixedPoint pt fe 𝓤₀
open import DomainTheory.Basics.Pointed pt fe 𝓤₀
open import Lifting.Construction 𝓤₀ hiding ()
open import Lifting.Miscelanea 𝓤₀
open import Naturals.Properties hiding (pred-succ)
open import PCF.Combinatory.PCFCombinators pt fe 𝓤₀
open import PCF.Lambda.AbstractSyntax pt
open import PCF.Lambda.ApplicativeApproximation pt
open import PCF.Lambda.BigStep 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 PCF.Lambda.Substitution pt fe pe

open IfZeroDenotationalSemantics pe

adequate : (σ : type) (d :   σ   ) (M : PCF ⟨⟩ σ)  𝓤₁ ̇
adequate ι        l t = 𝟙 × ((p : is-defined l)  t  numeral (value l p))
adequate (σ  σ₁) l t = (d :   σ   ) (M : PCF ⟨⟩ σ)
                            adequate σ d M
                            adequate σ₁ (pr₁ l d) (t · M)

lemma7-1-1 : {σ : type}
            (d :   σ   )
            (d' :   σ   )
            (d' ⊑⟨  σ    d)
            (M : PCF ⟨⟩ σ)
            adequate σ d M
            adequate σ d' M
lemma7-1-1 {ι} d d' x M (_ , o) =  , f
 where
  f : (p : is-defined d')  M  numeral (value d' p)
  f p = transport  -  M  numeral -) (e₂ ⁻¹) (o (=-to-is-defined e₁ p))
   where
    e₁ : d'  d
    e₁ = x p

    e₂ : value d' p  value d (=-to-is-defined e₁ p)
    e₂ = =-of-values-from-= e₁

lemma7-1-1 {σ  σ₁} f g x M p = γ
  where
   γ : (d :   σ   )
       N  adequate σ d N  adequate σ₁ (pr₁ g d) (M · N)
   γ d N a = IH
    where
     i : adequate σ₁ (pr₁ f d) (M · N)
     i = p d N a

     ii : pr₁ g d ⊑⟨  σ₁    pr₁ f d
     ii = x d

     IH : adequate σ₁ (pr₁ g d) (M · N)
     IH = lemma7-1-1 (pr₁ f d) (pr₁ g d) ii (M · N) i

adequacy-lubs : {σ : type} {I : 𝓤₀ ̇}
               (u : I    σ   )
               (δ : is-Directed (  σ  ) u)
               (t : PCF ⟨⟩ σ)
               ((i : I)  adequate σ (u i) t)
               adequate σ ( (  σ  ) δ) t
adequacy-lubs {ι} {I} u δ t a =  , g
 where
  g : (p : is-defined ( (  ι  ) δ))
     t  numeral (value ( (  ι  ) δ) p)
  g p = ∥∥-rec ∥∥-is-prop f p
   where
    f : (Σ i  I , is-defined (u i))
       t  numeral (value ( (  ι  ) δ) p)
    f (i , d) = transport  -  t  numeral -) value-lub-is-same (pr₂ (a i) d)
     where
      lub-is-same : u i   (  ι  ) δ
      lub-is-same = ∐-is-upperbound (  ι  ) δ i d

      value-lub-is-same : value (u i) d  value ( (  ι  ) δ) p
      value-lub-is-same = =-of-values-from-= lub-is-same

adequacy-lubs {σ  σ₁} {I} u δ t a p M x = IH
 where
  ptfam : I    σ₁   
  ptfam = pointwise-family (  σ  ) (  σ₁  ) u p

  ptfam-is-directed : is-Directed (  σ₁  ) ptfam
  ptfam-is-directed = pointwise-family-is-directed (  σ  ) (  σ₁  ) u δ p

  new_rel : (i : I)  adequate σ₁ (ptfam i) (t · M)
  new_rel i = a i p M x

  IH : adequate σ₁ ( (  σ₁  ) ptfam-is-directed) (t · M)
  IH = adequacy-lubs {σ₁} {I} ptfam ptfam-is-directed (t · M) new_rel

adequacy-step : {σ : type}
                (M M' : PCF ⟨⟩ σ)
               M ⊏̰ M'
               (a :   σ   )
               adequate σ a M
               adequate σ a M'
adequacy-step {ι} M M' r a ( , ρ) =  , f
 where
  f : (p : is-defined a)  M'  numeral (value a p)
  f p = r (value a p) (ρ p)

adequacy-step {σ  σ₁} M M' r (ϕ , _) rel d M₁ x = IH
 where
  new_rel : adequate σ₁ (ϕ d) (M · M₁)
  new_rel = rel d M₁ x

  IH : adequate σ₁ (ϕ d) (M' · M₁)
  IH = adequacy-step (M · M₁) (M' · M₁) (r M₁) (ϕ d) new_rel

adequacy-bottom : {σ : type}
                 (t : PCF ⟨⟩ σ)
                 adequate σ (  σ ) t
adequacy-bottom {ι}      t =  ,  p  𝟘-elim p)
adequacy-bottom {σ  σ₁} t =  _ M _  adequacy-bottom (t · M))

lemma7-3 : {σ : type}
          (M : PCF ⟨⟩ (σ  σ))
          (f :   σ  σ   )
          adequate (σ  σ) f M
          adequate σ (pr₁ (μ  σ ) f) (Fix M)
lemma7-3 {σ} M f rel = adequacy-lubs iter-M iter-M-is-directed (Fix M) fn
 where
  iter-M : Lift 𝓤₀     σ   
  iter-M (n , ) = iter  σ  n f

  iter-M-is-directed : is-Directed ( σ  ) iter-M
  iter-M-is-directed =
   pointwise-family-is-directed
    (( σ  ⟹ᵈᶜᵖᵒ⊥  σ ) ) ( σ  )
    (iter-c'  σ ) (iter-is-directed'  σ ) f

  fn : (n : Lift 𝓤₀ )  adequate σ (iter  σ  (lower n) f) (Fix M)
  fn (zero , )   = adequacy-bottom (Fix M)
  fn (succ n , ) = adequacy-step (M · Fix M) (Fix M) fix-⊏̰ (iter  σ  (succ n) f) IH₁
   where
    IH : adequate σ (iter  σ  n f) (Fix M)
    IH = fn (n , )

    IH₁ : adequate σ (iter  σ  (succ n) f) (M · (Fix M))
    IH₁ = rel (iter  σ  n f) (Fix M) IH

adequacy-succ : {n : } {Γ : Context n}
               (M : PCF Γ ι)
               (d :   Γ   )
               (f :  {A}  (x : Γ  A)  PCF ⟨⟩ A)
               adequate ι (pr₁  M ⟧ₑ d) (subst f M)
               adequate ι (pr₁  Succ M ⟧ₑ d) (subst f (Succ M))
adequacy-succ M d f ( , rel) =  , g
 where
  g : (p : is-defined (pr₁  Succ M ⟧ₑ d))
     subst f (Succ M)  numeral (value (pr₁  Succ M ⟧ₑ d) p)
  g p = ∥∥-functor  x  succ-arg x) (rel p)

pred-lemma :  {n : } {Γ : Context n} {k : }
            {M : PCF Γ ι}
            M ⇓' numeral k
            (Pred M) ⇓' numeral (pred k)
pred-lemma {n} {Γ} {zero}   x = pred-zero x
pred-lemma {n} {Γ} {succ k} x = pred-succ x

ifzero-lemma :
  {n : }
  {Γ : Context n} {k : }
  (M : PCF Γ ι)
  (M₁ : PCF Γ ι)
  (M₂ : PCF Γ ι)
  (f :  {A}  Γ  A  PCF ⟨⟩ A)
  subst f M  numeral k
  (d :   Γ   )
   (M-is-defined : is-defined (pr₁  M ⟧ₑ d))
   (δ : is-defined (⦅ifZero⦆₀ (pr₁  M₁ ⟧ₑ d) (pr₁  M₂ ⟧ₑ d) k))
   (M₁-rel : adequate ι (pr₁  M₁ ⟧ₑ d) (subst f M₁))
   (M₂-rel : adequate ι (pr₁  M₂ ⟧ₑ d) (subst f M₂))
  subst f (IfZero M M₁ M₂)
    numeral (value (⦅ifZero⦆₀ (pr₁  M₁ ⟧ₑ d) (pr₁  M₂ ⟧ₑ d) k) δ)
ifzero-lemma {n} {Γ} {zero} M M₁ M₂ f x d M-is-defined δ
             ( , M₁-rel) ( , M₂-rel) = γ
  where
   M₁-⇓ : subst f M₁  numeral (value (pr₁  M₁ ⟧ₑ d) δ)
   M₁-⇓ = M₁-rel δ

   γ : subst f (IfZero M M₁ M₂)
      numeral (value (⦅ifZero⦆₀ (pr₁  M₁ ⟧ₑ d) (pr₁  M₂ ⟧ₑ d) zero) δ)
   γ = ∥∥-functor  x  IfZero-zero (pr₁ x) (pr₂ x)) (binary-choice x M₁-⇓)

ifzero-lemma {n} {Γ} {succ k} M M₁ M₂ f x d M-is-defined δ
             ( , M₁-rel) ( , M₂-rel) = γ
 where
   M₂-⇓ : subst f M₂  numeral (value (pr₁  M₂ ⟧ₑ d) δ)
   M₂-⇓ = M₂-rel δ

   γ : subst f (IfZero M M₁ M₂)
      numeral (value (⦅ifZero⦆₀ (pr₁  M₁ ⟧ₑ d) (pr₁  M₂ ⟧ₑ d) (succ k)) δ)
   γ = ∥∥-functor  x  IfZero-succ (pr₁ x) (pr₂ x)) (binary-choice x M₂-⇓)

adequacy-pred : {n : } {Γ : Context n}
               (M : PCF Γ ι)
               (d :   Γ   )
               (f :  {A}  (x : Γ  A)  PCF ⟨⟩ A)
               adequate ι (pr₁  M ⟧ₑ d) (subst f M)
               adequate ι (pr₁  Pred M ⟧ₑ d) (subst f (Pred M))
adequacy-pred M d f ( , rel) =  , g
 where
   g : (p : is-defined (pr₁  Pred M ⟧ₑ d))
      subst f (Pred M)  numeral (value (pr₁  Pred M ⟧ₑ d) p)
   g p = ∥∥-functor pred-lemma (rel p)

adequacy-ifzero : {n : } {Γ : Context n}
                  (M : PCF Γ ι) (M₁ : PCF Γ ι) (M₂ : PCF Γ ι)
                  (d :   Γ   )
                  (f :  {A}  (x : Γ  A)  PCF ⟨⟩ A)
                 adequate ι (pr₁  M ⟧ₑ d) (subst f M)
                 adequate ι (pr₁  M₁ ⟧ₑ d) (subst f M₁)
                 adequate ι (pr₁  M₂ ⟧ₑ d) (subst f M₂)
                 adequate ι (pr₁  IfZero M M₁ M₂ ⟧ₑ d)
                             (subst f (IfZero M M₁ M₂))
adequacy-ifzero {n} {Γ} M M₁ M₂ d f ( , M-rel) M₁-rel M₂-rel =  , g
 where
  g : (p : is-defined (pr₁  IfZero M M₁ M₂ ⟧ₑ d))
     subst f (IfZero M M₁ M₂)  numeral (value (pr₁  IfZero M M₁ M₂ ⟧ₑ d) p)
  g (M-is-defined , δ) = ifzero-lemma
                          M
                          M₁
                          M₂
                          f
                          (M-rel M-is-defined)
                          d
                          M-is-defined
                          δ
                          M₁-rel
                          M₂-rel

lemma7-4 : {n : } {Γ : Context n} {τ : type}
           (M : PCF Γ τ)
           (d :   Γ   )
           (f :  {A}  (x : Γ  A)  PCF ⟨⟩ A)
           (g :  {A}  (x : Γ  A)  adequate A (extract x d) (f x))
          adequate τ (pr₁  M ⟧ₑ d) (subst f M)
lemma7-4 {n} {Γ} {.ι} Zero d f g =  , λ p   zero-id 

lemma7-4 {n} {Γ} {.ι} (Succ M) d f g = adequacy-succ M d f IH
 where
  IH : adequate ι (pr₁  M ⟧ₑ d) (subst f M)
  IH = lemma7-4 M d f g

lemma7-4 {n} {Γ} {.ι} (Pred M) d f g = adequacy-pred M d f IH
 where
  IH : adequate ι (pr₁  M ⟧ₑ d) (subst f M)
  IH = lemma7-4 M d f g

lemma7-4 {n} {Γ} {.ι} (IfZero M M₁ M₂) d f g =
 adequacy-ifzero M M₁ M₂ d f IH₀ IH₁ IH₂
 where
  IH₀ : adequate ι (pr₁  M ⟧ₑ d) (subst f M)
  IH₀ = lemma7-4 M d f g

  IH₁ : adequate ι (pr₁  M₁ ⟧ₑ d) (subst f M₁)
  IH₁ = lemma7-4 M₁ d f g

  IH₂ : adequate ι (pr₁  M₂ ⟧ₑ d) (subst f M₂)
  IH₂ = lemma7-4 M₂ d f g

lemma7-4 {n} {Γ} {.(_  _)} (ƛ {n} {Γ} {σ} {τ} M) d f g d₁ M₁ x = γ
 where
  IH : adequate τ (pr₁  M ⟧ₑ (d , d₁)) (subst (extend-with M₁ f) M)
  IH = lemma7-4 M (d , d₁) (extend-with M₁ f) extended-g
   where
    extended-g : {A : type} (x₁ : (Γ  σ)  A)
                adequate A (extract x₁ (d , d₁)) (extend-with M₁ f x₁)
    extended-g Z      = x
    extended-g (S x₁) = g x₁

  i : subst (extend-with M₁ f) M  subst (exts f) M [ M₁ ]
  i = subst-ext M M₁ f

  ii : subst (extend-with M₁ f) M ⊏̰ (subst f (ƛ M) · M₁)
  ii = transport⁻¹  -  - ⊏̰ (subst f (ƛ M) · M₁)) i β-⊏̰

  γ : adequate τ (pr₁ (pr₁  ƛ M ⟧ₑ d) d₁) (subst f (ƛ M) · M₁)
  γ = adequacy-step
       (subst (extend-with M₁ f) M)
       (subst f (ƛ M) · M₁)
       ii
       (pr₁ (pr₁  ƛ M ⟧ₑ d) d₁)
       IH

lemma7-4 (_·_ {n} {Γ} {σ} {σ₁} M M₁) d f g = IH₀ (pr₁  M₁ ⟧ₑ d) (subst f M₁) IH₁
 where
  IH₀ : adequate (σ  σ₁) (pr₁  M ⟧ₑ d) (subst f M)
  IH₀ = lemma7-4 M d f g

  IH₁ : adequate σ (pr₁  M₁ ⟧ₑ d) (subst f M₁)
  IH₁ = lemma7-4 M₁ d f g

lemma7-4 {n} {Γ} {σ} (v x) d f g = g x

lemma7-4 {n} {Γ} {σ} (Fix M) d f g = lemma7-3 (subst f M) (pr₁  M ⟧ₑ d) IH
 where
  IH : (d₁ :   σ   ) (M₁ : PCF ⟨⟩ σ)
      adequate σ d₁ M₁
      adequate σ (pr₁ (pr₁  M ⟧ₑ d) d₁) (subst  {A}  f) M · M₁)
  IH = lemma7-4 M d f g

adequacy : (M : PCF ⟨⟩ ι) (n : )  pr₁  M ⟧ₑ   η n  M  numeral n
adequacy M n p = pr₂ iv 
 where
  i : adequate ι (pr₁  M ⟧ₑ ) (subst ids M)
  i = lemma7-4 M  ids f
   where
    f :  {A}  (x : ⟨⟩  A)  adequate A (extract x ) (v x)
    f ()

  ii : subst ids M  M
  ii = sub-id M

  iii : adequate ι (pr₁  M ⟧ₑ ) M
  iii = transport (adequate ι (pr₁  M ⟧ₑ )) ii i

  iv : adequate ι (η n) M
  iv = transport  -  adequate ι - M) p iii

\end{code}