module A201605.TowardsAltArtemov.SyntaxCatholic where
open import Data.Nat using (ℕ ; zero ; suc)
open import Function using (_∘_)
open import Relation.Binary.PropositionalEquality using (_≡_ ; refl ; cong₂)
open import Relation.Nullary using (Dec ; yes ; no)
data _≥_ : ℕ → ℕ → Set where
id : ∀ {n} → n ≥ n
weak : ∀ {n′ n} → n′ ≥ n → suc n′ ≥ n
lift : ∀ {n′ n} → n′ ≥ n → suc n′ ≥ suc n
_○_ : ∀ {n″ n′ n} (p′ : n″ ≥ n′) (p : n′ ≥ n) → n″ ≥ n
id ○ p = p
weak p′ ○ p = weak (p′ ○ p)
lift p′ ○ id = lift p′
lift p′ ○ weak p = weak (p′ ○ p)
lift p′ ○ lift p = lift (p′ ○ p)
°to : ∀ n → n ≥ zero
°to zero = id
°to (suc n) = weak (°to n)
°str : ∀ {n n′} → n′ ≥ suc n → n′ ≥ n
°str id = weak id
°str (weak p) = weak (°str p)
°str (lift p) = weak p
°low : ∀ {n n′} → suc n′ ≥ suc n → n′ ≥ n
°low id = id
°low (weak p) = °str p
°low (lift p) = p
data °Var : ℕ → Set where
top : ∀ {n} → °Var (suc n)
pop : ∀ {n} → °Var n → °Var (suc n)
↑°var : ∀ {n′ n} (p : n′ ≥ n) → °Var n → °Var n′
↑°var id x = x
↑°var (weak p) x = pop (↑°var p x)
↑°var (lift p) top = top
↑°var (lift p) (pop x) = pop (↑°var p x)
↥°var : ∀ n → °Var 0 → °Var n
↥°var n ()
data °Tm (n : ℕ) : Set where
var : °Var n → °Tm n
lam : °Tm (suc n) → °Tm n
app : °Tm n → °Tm n → °Tm n
↑°tm : ∀ {n′ n} (p : n′ ≥ n) → °Tm n → °Tm n′
↑°tm p (var x) = var (↑°var p x)
↑°tm p (lam t) = lam (↑°tm (lift p) t)
↑°tm p (app t u) = app (↑°tm p t) (↑°tm p u)
↥°tm : ∀ n → °Tm 0 → °Tm n
↥°tm n = ↑°tm (°to n)
data Ty (n : ℕ) : Set where
★ : Ty n
_⊃_ : Ty n → Ty n → Ty n
infixr 5 _⊃_
↑ty : ∀ {n′ n} (p : n′ ≥ n) → Ty n → Ty n′
↑ty p ★ = ★
↑ty p (A ⊃ B) = ↑ty p A ⊃ ↑ty p B
↥ty : ∀ n → Ty 0 → Ty n
↥ty n = ↑ty (°to n)
↑ty-dist-≥-≥ : ∀ {n″ n′ n} (p′ : n″ ≥ n′) (p : n′ ≥ n) (A : Ty n) →
↑ty (p′ ○ p) A ≡ ↑ty p′ (↑ty p A)
↑ty-dist-≥-≥ p′ p ★ = refl
↑ty-dist-≥-≥ p′ p (A ⊃ B) = cong₂ _⊃_ (↑ty-dist-≥-≥ p′ p A) (↑ty-dist-≥-≥ p′ p B)
↥ty-dist-≥ : ∀ {n′ n} (p : n′ ≥ n) (A : Ty 0) →
↥ty n′ A ≡ ↑ty p (↥ty n A)
↥ty-dist-≥ {n = n} p = ↑ty-dist-≥-≥ p (°to n)
↑ty-pres-★ : ∀ {n′ n} {p : n′ ≥ n} {A : Ty n} → A ≡ ★ → ↑ty p A ≡ ★
↑ty-pres-★ refl = refl
↑ty-pres-⊃ : ∀ {n′ n} {p : n′ ≥ n} {A B A⊃B : Ty n} → A⊃B ≡ A ⊃ B → ↑ty p A⊃B ≡ ↑ty p A ⊃ ↑ty p B
↑ty-pres-⊃ refl = refl
⊃⁻ᴬ : ∀ {n} {A A′ B B′ : Ty n} → (A ⊃ B) ≡ (A′ ⊃ B′) → A ≡ A′
⊃⁻ᴬ refl = refl
⊃⁻ᴮ : ∀ {n} {A A′ B B′ : Ty n} → (A ⊃ B) ≡ (A′ ⊃ B′) → B ≡ B′
⊃⁻ᴮ refl = refl
_≟_ : ∀ {g} → (A A′ : Ty g) → Dec (A ≡ A′)
★ ≟ ★ = yes refl
★ ≟ (A ⊃ B) = no λ ()
(A ⊃ B) ≟ ★ = no λ ()
(A ⊃ B) ≟ (A′ ⊃ B′) with A ≟ A′ | B ≟ B′
(A ⊃ B) ≟ (.A ⊃ .B) | yes refl | yes refl = yes refl
... | no A≢A′ | _ = no (A≢A′ ∘ ⊃⁻ᴬ)
... | _ | no B≢B′ = no (B≢B′ ∘ ⊃⁻ᴮ)
data Cx : Set where
∅ : Cx
_,_ : Cx → Ty 0 → Cx
ⁿ⌊_⌋ : (Γ : Cx) → ℕ
ⁿ⌊ ∅ ⌋ = zero
ⁿ⌊ Γ , A ⌋ = suc ⁿ⌊ Γ ⌋
data _⊇_ : Cx → Cx → Set where
id : ∀ {Γ} → Γ ⊇ Γ
weak : ∀ {Γ Γ′} (A : Ty 0) → Γ′ ⊇ Γ → (Γ′ , A) ⊇ Γ
lift : ∀ {Γ Γ′} (A : Ty 0) → Γ′ ⊇ Γ → (Γ′ , A) ⊇ (Γ , A)
ᵖ⌊_⌋ : ∀ {Γ′ Γ} (η : Γ ⊇ Γ′) → ⁿ⌊ Γ ⌋ ≥ ⁿ⌊ Γ′ ⌋
ᵖ⌊ id ⌋ = id
ᵖ⌊ weak A η ⌋ = weak ᵖ⌊ η ⌋
ᵖ⌊ lift A η ⌋ = lift ᵖ⌊ η ⌋
to : ∀ Γ → Γ ⊇ ∅
to ∅ = id
to (Γ , A) = weak A (to Γ)
str : ∀ {Γ′ Γ} (A : Ty 0) → Γ′ ⊇ (Γ , A) → Γ′ ⊇ Γ
str A id = weak A id
str A (weak B η) = weak B (str A η)
str A (lift .A η) = weak A η
low : ∀ {Γ′ Γ} (A : Ty 0) → (Γ′ , A) ⊇ (Γ , A) → Γ′ ⊇ Γ
low A id = id
low A (weak .A η) = str A η
low A (lift .A η) = η
↑ty-dist-≥-⊇ : ∀ {Δ″ Δ′ Δ} (p′ : ⁿ⌊ Δ″ ⌋ ≥ ⁿ⌊ Δ′ ⌋) (η : Δ′ ⊇ Δ) (A : Ty ⁿ⌊ Δ ⌋) →
↑ty (p′ ○ ᵖ⌊ η ⌋) A ≡ ↑ty p′ (↑ty ᵖ⌊ η ⌋ A)
↑ty-dist-≥-⊇ p′ η = ↑ty-dist-≥-≥ p′ ᵖ⌊ η ⌋
↑ty-dist-⊇-≥ : ∀ {Δ″ Δ′ Δ} (η′ : Δ″ ⊇ Δ′) (p : ⁿ⌊ Δ′ ⌋ ≥ ⁿ⌊ Δ ⌋) (A : Ty ⁿ⌊ Δ ⌋) →
↑ty (ᵖ⌊ η′ ⌋ ○ p) A ≡ ↑ty ᵖ⌊ η′ ⌋ (↑ty p A)
↑ty-dist-⊇-≥ η′ p = ↑ty-dist-≥-≥ ᵖ⌊ η′ ⌋ p
↑ty-dist-⊇-⊇ : ∀ {Δ″ Δ′ Δ} (η′ : Δ″ ⊇ Δ′) (η : Δ′ ⊇ Δ) (A : Ty ⁿ⌊ Δ ⌋) →
↑ty (ᵖ⌊ η′ ⌋ ○ ᵖ⌊ η ⌋) A ≡ ↑ty ᵖ⌊ η′ ⌋ (↑ty ᵖ⌊ η ⌋ A)
↑ty-dist-⊇-⊇ η′ η = ↑ty-dist-≥-≥ ᵖ⌊ η′ ⌋ ᵖ⌊ η ⌋
↥ty-dist-⊇ : ∀ {Δ′ Δ} (η : Δ′ ⊇ Δ) (A : Ty 0) →
↥ty ⁿ⌊ Δ′ ⌋ A ≡ ↑ty ᵖ⌊ η ⌋ (↥ty ⁿ⌊ Δ ⌋ A)
↥ty-dist-⊇ η = ↥ty-dist-≥ ᵖ⌊ η ⌋
data Var : Cx → Ty 0 → Set where
top : ∀ {Γ} (A : Ty 0) → Var (Γ , A) A
pop : ∀ {Γ} {A : Ty 0} (B : Ty 0) → Var Γ A → Var (Γ , B) A
↑var : ∀ {Γ′ Γ} {A : Ty 0} (η : Γ′ ⊇ Γ) → Var Γ A → Var Γ′ A
↑var id x = x
↑var (weak B η) x = pop B (↑var η x)
↑var (lift A η) (top .A) = top A
↑var (lift B η) (pop .B x) = pop B (↑var η x)
↥var : ∀ Γ {A : Ty 0} → Var ∅ A → Var Γ A
↥var Γ ()
data Tm (Γ : Cx) : Ty ⁿ⌊ Γ ⌋ → Set where
var : ∀ {A : Ty 0} →
Var Γ A →
{A′ : Ty ⁿ⌊ Γ ⌋} {{_ : A′ ≡ ↥ty ⁿ⌊ Γ ⌋ A}} →
Tm Γ A′
lam : ∀ (A : Ty 0) {B : Ty 0} →
Tm (Γ , A) (↥ty ⁿ⌊ Γ , A ⌋ B) →
{A⊃B′ : Ty ⁿ⌊ Γ ⌋} {{_ : A⊃B′ ≡ ↥ty ⁿ⌊ Γ ⌋ (A ⊃ B)}} →
Tm Γ A⊃B′
app : ∀ {A B : Ty 0} →
Tm Γ (↥ty ⁿ⌊ Γ ⌋ (A ⊃ B)) → Tm Γ (↥ty ⁿ⌊ Γ ⌋ A) →
{B′ : Ty ⁿ⌊ Γ ⌋} {{_ : B′ ≡ ↥ty ⁿ⌊ Γ ⌋ B}} →
Tm Γ B′
≪tm : ∀ {Δ′ Δ} {A : Ty 0} (η : Δ′ ⊇ Δ) →
Tm Δ′ (↑ty ᵖ⌊ η ⌋ (↥ty ⁿ⌊ Δ ⌋ A)) →
Tm Δ′ (↥ty ⁿ⌊ Δ′ ⌋ A)
≪tm {A = A} η x rewrite ↥ty-dist-⊇ η A = x
≫tm : ∀ {Δ′ Δ} {A : Ty 0} (η : Δ′ ⊇ Δ) →
Tm Δ′ (↥ty ⁿ⌊ Δ′ ⌋ A) →
Tm Δ′ (↑ty ᵖ⌊ η ⌋ (↥ty ⁿ⌊ Δ ⌋ A))
≫tm {A = A} η x rewrite ↥ty-dist-⊇ η A = x
↑tm : ∀ {Γ′ Γ} {A : Ty ⁿ⌊ Γ ⌋} (η : Γ′ ⊇ Γ) → Tm Γ A → Tm Γ′ (↑ty ᵖ⌊ η ⌋ A)
↑tm η (var x {{refl}}) = ≫tm η (var (↑var η x))
↑tm η (lam A t {{refl}}) = ≫tm η (lam A (≪tm (lift A η) (↑tm (lift A η) t)))
↑tm η (app t u {{refl}}) = ≫tm η (app (≪tm η (↑tm η t)) (≪tm η (↑tm η u)))
↥tm : ∀ Γ {A : Ty 0} → Tm ∅ A → Tm Γ (↥ty ⁿ⌊ Γ ⌋ A)
↥tm Γ = ↑tm (to Γ)
data Ne (Ξ : (Δ : Cx) → Ty ⁿ⌊ Δ ⌋ → Set) (Γ : Cx) : Ty ⁿ⌊ Γ ⌋ → Set where
var : ∀ {A : Ty 0} →
Var Γ A →
{A′ : Ty ⁿ⌊ Γ ⌋} {{_ : A′ ≡ ↥ty ⁿ⌊ Γ ⌋ A}} →
Ne Ξ Γ A′
app : ∀ {A B : Ty 0} →
Ne Ξ Γ (↥ty ⁿ⌊ Γ ⌋ (A ⊃ B)) → Ξ Γ (↥ty ⁿ⌊ Γ ⌋ A) →
{B′ : Ty ⁿ⌊ Γ ⌋} {{_ : B′ ≡ ↥ty ⁿ⌊ Γ ⌋ B}} →
Ne Ξ Γ B′
data Nf (Δ : Cx) : Ty ⁿ⌊ Δ ⌋ → Set where
ne : Ne Nf Δ ★ → Nf Δ ★
lam : ∀ (A : Ty 0) {B : Ty 0} →
Nf (Δ , A) (↥ty ⁿ⌊ Δ , A ⌋ B) →
{A⊃B′ : Ty ⁿ⌊ Δ ⌋} {{_ : A⊃B′ ≡ ↥ty ⁿ⌊ Δ ⌋ (A ⊃ B)}} →
Nf Δ A⊃B′
mutual
data Val (Δ : Cx) : Ty ⁿ⌊ Δ ⌋ → Set where
ne : ∀ {A : Ty ⁿ⌊ Δ ⌋} → Ne Val Δ A → Val Δ A
lam : ∀ {Γ} (A : Ty 0) {B : Ty 0} →
Tm (Γ , A) (↥ty ⁿ⌊ Γ , A ⌋ B) → Env Δ Γ →
{A⊃B′ : Ty ⁿ⌊ Δ ⌋} {{_ : A⊃B′ ≡ ↥ty ⁿ⌊ Δ ⌋ (A ⊃ B)}} →
Val Δ A⊃B′
data Env (Δ : Cx) : Cx → Set where
∅ : Env Δ ∅
_,_ : ∀ {Γ} {A : Ty 0} →
Env Δ Γ → Val Δ (↥ty ⁿ⌊ Δ ⌋ A) →
Env Δ (Γ , A)
≪nen : ∀ {Δ′ Δ} {A : Ty 0} (η : Δ′ ⊇ Δ) →
Ne Nf Δ′ (↑ty ᵖ⌊ η ⌋ (↥ty ⁿ⌊ Δ ⌋ A)) →
Ne Nf Δ′ (↥ty ⁿ⌊ Δ′ ⌋ A)
≪nen {A = A} η x rewrite ↥ty-dist-⊇ η A = x
≫nen : ∀ {Δ′ Δ} {A : Ty 0} (η : Δ′ ⊇ Δ) →
Ne Nf Δ′ (↥ty ⁿ⌊ Δ′ ⌋ A) →
Ne Nf Δ′ (↑ty ᵖ⌊ η ⌋ (↥ty ⁿ⌊ Δ ⌋ A))
≫nen {A = A} η x rewrite ↥ty-dist-⊇ η A = x
≪nev : ∀ {Δ′ Δ} {A : Ty 0} (η : Δ′ ⊇ Δ) →
Ne Val Δ′ (↑ty ᵖ⌊ η ⌋ (↥ty ⁿ⌊ Δ ⌋ A)) →
Ne Val Δ′ (↥ty ⁿ⌊ Δ′ ⌋ A)
≪nev {A = A} η x rewrite ↥ty-dist-⊇ η A = x
≫nev : ∀ {Δ′ Δ} {A : Ty 0} (η : Δ′ ⊇ Δ) →
Ne Val Δ′ (↥ty ⁿ⌊ Δ′ ⌋ A) →
Ne Val Δ′ (↑ty ᵖ⌊ η ⌋ (↥ty ⁿ⌊ Δ ⌋ A))
≫nev {A = A} η x rewrite ↥ty-dist-⊇ η A = x
≪nf : ∀ {Δ′ Δ} {A : Ty 0} (η : Δ′ ⊇ Δ) →
Nf Δ′ (↑ty ᵖ⌊ η ⌋ (↥ty ⁿ⌊ Δ ⌋ A)) →
Nf Δ′ (↥ty ⁿ⌊ Δ′ ⌋ A)
≪nf {A = A} η x rewrite ↥ty-dist-⊇ η A = x
≫nf : ∀ {Δ′ Δ} {A : Ty 0} (η : Δ′ ⊇ Δ) →
Nf Δ′ (↥ty ⁿ⌊ Δ′ ⌋ A) →
Nf Δ′ (↑ty ᵖ⌊ η ⌋ (↥ty ⁿ⌊ Δ ⌋ A))
≫nf {A = A} η x rewrite ↥ty-dist-⊇ η A = x
≪val : ∀ {Δ′ Δ} {A : Ty 0} (η : Δ′ ⊇ Δ) →
Val Δ′ (↑ty ᵖ⌊ η ⌋ (↥ty ⁿ⌊ Δ ⌋ A)) →
Val Δ′ (↥ty ⁿ⌊ Δ′ ⌋ A)
≪val {A = A} η x rewrite ↥ty-dist-⊇ η A = x
≫val : ∀ {Δ′ Δ} {A : Ty 0} (η : Δ′ ⊇ Δ) →
Val Δ′ (↥ty ⁿ⌊ Δ′ ⌋ A) →
Val Δ′ (↑ty ᵖ⌊ η ⌋ (↥ty ⁿ⌊ Δ ⌋ A))
≫val {A = A} η x rewrite ↥ty-dist-⊇ η A = x
mutual
↑nen : ∀ {Δ′ Δ} {A : Ty ⁿ⌊ Δ ⌋} (η : Δ′ ⊇ Δ) →
Ne Nf Δ A →
Ne Nf Δ′ (↑ty ᵖ⌊ η ⌋ A)
↑nen η (var x {{refl}}) = ≫nen η (var (↑var η x))
↑nen η (app t u {{refl}}) = ≫nen η (app (≪nen η (↑nen η t)) (≪nf η (↑nf η u)))
↑nev : ∀ {Δ′ Δ} {A : Ty ⁿ⌊ Δ ⌋} (η : Δ′ ⊇ Δ) →
Ne Val Δ A →
Ne Val Δ′ (↑ty ᵖ⌊ η ⌋ A)
↑nev η (var x {{refl}}) = ≫nev η (var (↑var η x))
↑nev η (app t u {{refl}}) = ≫nev η (app (≪nev η (↑nev η t)) (≪val η (↑val η u)))
↑nf : ∀ {Δ′ Δ} {A : Ty ⁿ⌊ Δ ⌋} (η : Δ′ ⊇ Δ) →
Nf Δ A →
Nf Δ′ (↑ty ᵖ⌊ η ⌋ A)
↑nf η (ne n) = ne (↑nen η n)
↑nf η (lam A t {{refl}}) = ≫nf η (lam A (≪nf (lift A η) (↑nf (lift A η) t)))
↑val : ∀ {Δ′ Δ} {A : Ty ⁿ⌊ Δ ⌋} (η : Δ′ ⊇ Δ) →
Val Δ A →
Val Δ′ (↑ty ᵖ⌊ η ⌋ A)
↑val η (ne n) = ne (↑nev η n)
↑val η (lam A t γ {{refl}}) = ≫val η (lam A t (↑env η γ))
↑env : ∀ {Δ′ Δ Γ} (η : Δ′ ⊇ Δ) →
Env Δ Γ →
Env Δ′ Γ
↑env η ∅ = ∅
↑env η (γ , v) = (↑env η γ , ≪val η (↑val η v))
↥nen : ∀ Δ {A : Ty 0} → Ne Nf ∅ A → Ne Nf Δ (↥ty ⁿ⌊ Δ ⌋ A)
↥nen Δ = ↑nen (to Δ)
↥nev : ∀ Δ {A : Ty 0} → Ne Val ∅ A → Ne Val Δ (↥ty ⁿ⌊ Δ ⌋ A)
↥nev Δ = ↑nev (to Δ)
↥nf : ∀ Δ {A : Ty 0} → Nf ∅ A → Nf Δ (↥ty ⁿ⌊ Δ ⌋ A)
↥nf Δ = ↑nf (to Δ)
↥val : ∀ Δ {A : Ty 0} → Val ∅ A → Val Δ (↥ty ⁿ⌊ Δ ⌋ A)
↥val Δ = ↑val (to Δ)
↥env : ∀ Δ {Γ} → Env ∅ Γ → Env Δ Γ
↥env Δ = ↑env (to Δ)