module extra.es where
import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_; refl)
open import Relation.Nullary.Negation using (¬_)
open import Data.Empty using (⊥; ⊥-elim)
open import Relation.Nullary.Decidable using (True; toWitness)
open import Data.Product using (_×_; _,_; ∃-syntax; Σ-syntax)
open import Data.Sum using (_⊎_; inj₁; inj₂) renaming ([_,_] to case-⊎)
infixr 7 _⇒_
data Type : Set where
`ℕ : Type
_⇒_ : Type → Type → Type
infixl 5 _,-_
data Context : Set where
∅ : Context
_,-_ : Context → Type → Context
variable
A B C : Type
Γ Δ Σ : Context
infix 4 _⊢_
infix 5 ƛ_
infixl 7 _·_
infixl 9 _[_]
data Subst : Context → Context → Set
data _⊢_ : Context → Type → Set where
⋆ :
Γ ,- A ⊢ A
ƛ_ :
(M : Γ ,- A ⊢ B)
→
Γ ⊢ A ⇒ B
_·_ :
(M : Γ ⊢ A ⇒ B)
(N : Γ ⊢ A)
→
Γ ⊢ B
_[_] :
(M : Γ ⊢ A)
(σ : Subst Γ Δ)
→
Δ ⊢ A
variable
L M N L' M' N' : Γ ⊢ A
σ τ υ : Subst Γ Δ
infixr 6 _•_
infixr 5 _⨟_
data Subst where
id :
Subst Γ Γ
↑ :
Subst Γ (Γ ,- A)
_•_ :
(M : Δ ⊢ A)
(σ : Subst Γ Δ)
→
Subst (Γ ,- A) Δ
_⨟_ :
(σ : Subst Γ Δ)
(τ : Subst Δ Σ)
→
Subst Γ Σ
data Shifts : Subst Γ Δ → Set where
S-↑ : Shifts {Γ} {Γ ,- A} ↑
S-⨟ : Shifts σ → Shifts (↑ ⨟ σ)
module basic where
data σNf : Γ ⊢ A → Set where
σNf-⋆ : σNf {Γ ,- A} ⋆
σNf-↑ : Shifts σ → σNf (⋆ [ σ ])
σNf-· : σNf M → σNf N → σNf (M · N)
σNf-ƛ : σNf M → σNf (ƛ M)
data σNf-Subst : Subst Γ Δ → Set where
σNf-si : σNf-Subst {Γ} id
σNf-su : σNf-Subst {Γ} {Γ ,- A} ↑
σNf-sc : σNf-Subst σ → σNf-Subst (M • σ)
infix 2 _—→_ _~→_
data _~→_ : Subst Γ Δ → Subst Γ Δ → Set where
id⨟ :
id ⨟ σ ~→ σ
↑⨟id :
↑ ⨟ (id {Γ ,- A}) ~→ ↑
↑⨟• :
↑ ⨟ (M • σ) ~→ σ
•⨟ :
(M • σ) ⨟ τ ~→ M [ τ ] • (σ ⨟ τ)
⨟⨟ :
(σ ⨟ τ) ⨟ υ ~→ σ ⨟ (τ ⨟ υ)
data _—→_ : Γ ⊢ A → Γ ⊢ A → Set where
β-ƛ :
(VM : σNf M)
→
(ƛ M) · N —→ M [ N • id ]
σ-⋆ :
⋆ [ (id {Γ ,- A}) ] —→ ⋆
σ-• :
⋆ [ M • σ ] —→ M
σ-· :
(M · N) [ σ ] —→ M [ σ ] · N [ σ ]
σ-ƛ :
(ƛ M) [ σ ] —→ ƛ M [ ⋆ • (σ ⨟ ↑) ]
σ-⨟ :
M [ σ ] [ τ ] —→ M [ σ ⨟ τ ]
open import Relation.Binary.Construct.Closure.ReflexiveTransitive
using (Star; ε; _◅_; _◅◅_)
_—↠_ : (M N : Γ ⊢ A) → Set
M —↠ N = Star _—→_ M N
confluence : L —↠ M → L —↠ M' → ∃[ N ] (M —↠ N) × (M' —↠ N)
confluence ε L—↠M' = _ , L—↠M' , ε
confluence L—→M ε = _ , ε , L—→M
confluence (β-ƛ VM ◅ L₁—↠M) (β-ƛ VM₁ ◅ L₁'—↠M') = confluence L₁—↠M L₁'—↠M'
confluence (σ-⋆ ◅ L₁—↠M) (σ-⋆ ◅ L₁'—↠M') = confluence L₁—↠M L₁'—↠M'
confluence (σ-• ◅ L₁—↠M) (σ-• ◅ L₁'—↠M') = confluence L₁—↠M L₁'—↠M'
confluence (σ-· ◅ L₁—↠M) (σ-· ◅ L₁'—↠M') = confluence L₁—↠M L₁'—↠M'
confluence (σ-ƛ ◅ L₁—↠M) (σ-ƛ ◅ L₁'—↠M') = confluence L₁—↠M L₁'—↠M'
confluence (σ-⨟ ◅ L₁—↠M) (σ-⨟ ◅ L₁'—↠M') = confluence L₁—↠M L₁'—↠M'