module A201801.FullS4Normalisation where
open import A201801.Prelude
open import A201801.Category
open import A201801.List
open List²
open import A201801.ListLemmas
open import A201801.AllList
open import A201801.FullS4Propositions
open import A201801.FullS4StandardDerivations
open import A201801.FullS4BidirectionalDerivationsForNormalisation
import A201801.FullS4EmbeddingOfFullIPL as OfIPL
import A201801.FullS4ProjectionToFullIPL as ToIPL
import A201801.FullIPLPropositions as IPL
import A201801.FullIPLDerivations as IPL
import A201801.FullIPLNormalisation as IPL
record Model : Set₁
where
field
World : Set
Ground : World → String → Set
Explode : World → Form → Set
_≥_ : World → World → Set
id≥ : ∀ {W} → W ≥ W
_∘≥_ : ∀ {W W′ W″} → W′ ≥ W → W″ ≥ W′
→ W″ ≥ W
relG : ∀ {P W W′} → W′ ≥ W → Ground W P
→ Ground W′ P
peek : World → List Assert
peek≥ : ∀ {W W′} → W′ ≥ W
→ peek W′ ⊇ peek W
open Model {{...}} public
mutual
infix 3 _⊩_value
_⊩_value : ∀ {{_ : Model}} → World → Form → Set
W ⊩ ι P value = Ground W P
W ⊩ A ⊃ B value = ∀ {W′ : World} → W′ ≥ W → W′ ⊩ A thunk
→ W′ ⊩ B thunk
W ⊩ A ∧ B value = W ⊩ A thunk × W ⊩ B thunk
W ⊩ 𝟏 value = ⊤
W ⊩ 𝟎 value = ⊥
W ⊩ A ∨ B value = W ⊩ A thunk ⊎ W ⊩ B thunk
W ⊩ □ A value = W ⊩ ⟪⊫ A ⟫ chunk
infix 3 _⊩_thunk
_⊩_thunk : ∀ {{_ : Model}} → World → Form → Set
W ⊩ A thunk = ∀ {B} {W′ : World} → W′ ≥ W → (∀ {W″ : World} → W″ ≥ W′ → W″ ⊩ A value
→ Explode W″ B)
→ Explode W′ B
infix 3 _⊩_chunk
_⊩_chunk : ∀ {{_ : Model}} → World → Assert → Set
W ⊩ ⟪⊫ A ⟫ chunk = ToIPL.↓ₐₛ (peek W) IPL.⊢ ToIPL.↓ₚ A true × W ⊩ A thunk
infix 3 _⊩_allthunk
_⊩_allthunk : ∀ {{_ : Model}} → World → List Form → Set
W ⊩ Γ allthunk = All (W ⊩_thunk) Γ
infix 3 _⊩_allchunk
_⊩_allchunk : ∀ {{_ : Model}} → World → List Assert → Set
W ⊩ Δ allchunk = All (W ⊩_chunk) Δ
syn : ∀ {{_ : Model}} {A} {W : World} → W ⊩ ⟪⊫ A ⟫ chunk
→ ToIPL.↓ₐₛ (peek W) IPL.⊢ ToIPL.↓ₚ A true
syn (𝒟 , k) = 𝒟
syns : ∀ {{_ : Model}} {Δ} {W : World} → W ⊩ Δ allchunk
→ ToIPL.↓ₐₛ (peek W) IPL.⊢ ToIPL.↓ₐₛ Δ alltrue
syns ∙ = ∙
syns (_,_ {A = ⟪⊫ A ⟫} δ c) = syns δ , syn {A} c
sem : ∀ {{_ : Model}} {A} {W : World} → W ⊩ ⟪⊫ A ⟫ chunk
→ W ⊩ A thunk
sem (𝒟 , k) = k
mutual
rel : ∀ {{_ : Model}} {A} {W W′ : World} → W′ ≥ W → W ⊩ A value
→ W′ ⊩ A value
rel {ι P} η 𝒟 = relG η 𝒟
rel {A ⊃ B} η f = \ η′ k → f (η ∘≥ η′) k
rel {A ∧ B} η (k₁ , k₂) = threl {A} η k₁ , threl {B} η k₂
rel {𝟏} η ∙ = ∙
rel {𝟎} η ()
rel {A ∨ B} η (inj₁ k₁) = inj₁ (threl {A} η k₁)
rel {A ∨ B} η (inj₂ k₂) = inj₂ (threl {B} η k₂)
rel {□ A} η c = chrel {⟪⊫ A ⟫} η c
threl : ∀ {{_ : Model}} {A} {W W′ : World} → W′ ≥ W → W ⊩ A thunk
→ W′ ⊩ A thunk
threl η k = \ η′ f → k (η ∘≥ η′) f
chrel : ∀ {{_ : Model}} {A} {W W′ : World} → W′ ≥ W → W ⊩ A chunk
→ W′ ⊩ A chunk
chrel {⟪⊫ A ⟫} η c = IPL.ren (ToIPL.↓⊇ₐₛ (peek≥ η)) (syn {A} c) , threl {A} η (sem {A} c)
threls : ∀ {{_ : Model}} {Γ} {W W′ : World} → W′ ≥ W → W ⊩ Γ allthunk
→ W′ ⊩ Γ allthunk
threls η γ = maps (\ {A} k {B} {W′} → threl {A} η (\ {C} {W″} → k {C} {W″})) γ
chrels : ∀ {{_ : Model}} {Δ} {W W′ : World} → W′ ≥ W → W ⊩ Δ allchunk
→ W′ ⊩ Δ allchunk
chrels η δ = maps (\ {A} c → chrel {A} η c) δ
return : ∀ {{_ : Model}} {A} {W : World} → W ⊩ A value
→ W ⊩ A thunk
return {A} a = \ η f → f id≥ (rel {A} η a)
bind : ∀ {{_ : Model}} {A B} {W : World} → W ⊩ A thunk → (∀ {W′ : World} → W′ ≥ W → W′ ⊩ A value
→ W′ ⊩ B thunk)
→ W ⊩ B thunk
bind k f = \ η f′ →
k η (\ η′ a →
f (η ∘≥ η′) a id≥ (\ η″ b →
f′ (η′ ∘≥ η″) b))
infix 3 _⊨_valid[_]
_⊨_valid[_] : List Assert → Form → List Form → Set₁
Δ ⊨ A valid[ Γ ] = ∀ {{_ : Model}} {W : World} → W ⊩ Δ allchunk → W ⊩ Γ allthunk
→ W ⊩ A thunk
↓ : ∀ {Δ Γ A} → Δ ⊢ A valid[ Γ ]
→ Δ ⊨ A valid[ Γ ]
↓ (var i) δ γ = get γ i
↓ (lam {A} {B} 𝒟) δ γ = return {A ⊃ B} (\ η k →
↓ 𝒟 (chrels η δ) (threls η γ , k))
↓ (app {A} {B} 𝒟 ℰ) δ γ = bind {A ⊃ B} {B} (↓ 𝒟 δ γ) (\ η f →
f id≥ (↓ ℰ (chrels η δ) (threls η γ)))
↓ (pair {A} {B} 𝒟 ℰ) δ γ = return {A ∧ B} (↓ 𝒟 δ γ , ↓ ℰ δ γ)
↓ (fst {A} {B} 𝒟) δ γ = bind {A ∧ B} {A} (↓ 𝒟 δ γ) (\ { η (k₁ , k₂) → k₁ })
↓ (snd {A} {B} 𝒟) δ γ = bind {A ∧ B} {B} (↓ 𝒟 δ γ) (\ { η (k₁ , k₂) → k₂ })
↓ unit δ γ = return {𝟏} ∙
↓ (abort {A} 𝒟) δ γ = bind {𝟎} {A} (↓ 𝒟 δ γ) (\ η ())
↓ (inl {A} {B} 𝒟) δ γ = return {A ∨ B} (inj₁ (↓ 𝒟 δ γ))
↓ (inr {A} {B} 𝒟) δ γ = return {A ∨ B} (inj₂ (↓ 𝒟 δ γ))
↓ (case {A} {B} {C} 𝒟 ℰ ℱ) δ γ = bind {A ∨ B} {C} (↓ 𝒟 δ γ) (\ { η (inj₁ k₁) → ↓ ℰ (chrels η δ) (threls η γ , k₁)
; η (inj₂ k₂) → ↓ ℱ (chrels η δ) (threls η γ , k₂)
})
↓ (mvar {A} i) δ γ = sem {A} (get δ i)
↓ (box {A} 𝒟) δ γ = return {□ A} (IPL.sub (syns δ) (ToIPL.↓ 𝒟) , ↓ 𝒟 δ ∙)
↓ (letbox {A} {B} 𝒟 ℰ) δ γ = bind {□ A} {B} (↓ 𝒟 δ γ) (\ η c →
↓ ℰ (chrels η δ , c) (threls η γ))
ren² : ∀ {Δ Δ′ Γ Γ′ A} → Δ′ ⨾ Γ′ ⊇² Δ ⨾ Γ → Δ ⊢ A neutral[ Γ ]
→ Δ′ ⊢ A neutral[ Γ′ ]
ren² (η₁ , η₂) 𝒟 = mrenᵣ η₁ (renᵣ η₂ 𝒟)
private
instance
canon : Model
canon = record
{ World = List² Assert Form
; Ground = \ { (Δ ⨾ Γ) P → Δ ⊢ ι P neutral[ Γ ] }
; Explode = \ { (Δ ⨾ Γ) A → Δ ⊢ A normal[ Γ ] }
; _≥_ = _⊇²_
; id≥ = id
; _∘≥_ = _∘_
; relG = ren²
; peek = proj₁
; peek≥ = proj₁
}