module Syntax where
open import Library
infixr 6 _⇒_
infixr 4 _,_
data Ty : Set where
★ : Ty
_⇒_ : (a b : Ty) → Ty
data Cxt : Set where
ε : Cxt
_,_ : (Γ : Cxt) (a : Ty) → Cxt
data Var : (Γ : Cxt) (a : Ty) → Set where
zero : ∀ {Γ a} → Var (Γ , a) a
suc : ∀ {Γ a b} (x : Var Γ a) → Var (Γ , b) a
data Tm (Γ : Cxt) : (a : Ty) → Set where
var : ∀ {a} (x : Var Γ a) → Tm Γ a
abs : ∀ {a b} (t : Tm (Γ , a) b) → Tm Γ (a ⇒ b)
app : ∀ {a b} (t : Tm Γ (a ⇒ b)) (u : Tm Γ a) → Tm Γ b
data GNe (Arg : Cxt → Ty → Set) (Γ : Cxt) : Ty → Set where
var : ∀{a} (x : Var Γ a) → GNe Arg Γ a
app : ∀{a b} (n : GNe Arg Γ (a ⇒ b)) (o : Arg Γ a) → GNe Arg Γ b
mutual
Ne = GNe Nf
data Nf (Γ : Cxt) : Ty → Set where
abs : ∀{a b} (o : Nf (Γ , a) b) → Nf Γ (a ⇒ b)
ne : (n : Ne Γ ★) → Nf Γ ★
mutual
embNe : ∀{Γ a} → Ne Γ a → Tm Γ a
embNe (var x) = var x
embNe (app t u) = app (embNe t) (embNf u)
embNf : ∀{Γ a} → Nf Γ a → Tm Γ a
embNf (ne t) = embNe t
embNf (abs t) = abs (embNf t)
mutual
data Env (i : Size) (Δ : Cxt) : (Γ : Cxt) → Set where
ε : Env i Δ ε
_,_ : ∀ {Γ a} (ρ : Env i Δ Γ) (v : Val i Δ a) → Env i Δ (Γ , a)
NeVal = λ i → GNe (Val i)
data Val (i : Size) (Δ : Cxt) : (a : Ty) → Set where
ne : ∀{a} (n : NeVal i Δ a) → Val i Δ a
lam : ∀{Γ a b} (t : Tm (Γ , a) b) (ρ : Env i Δ Γ) → Val i Δ (a ⇒ b)
later : ∀{a} (v∞ : ∞Val i Δ a) → Val i Δ a
record ∞Val (i : Size) (Δ : Cxt) (a : Ty) : Set where
coinductive
constructor ∞val
field
force : {j : Size< i} → Val j Δ a
open ∞Val public
mutual
Val∋_≈⟨_⟩≈_ = λ {Δ}{a} a? i b? → Val∋_≈_ {i}{Δ}{a} a? b?
NeVal∋_≈⟨_⟩≈_ = λ {Δ}{a} a? i b? → NeVal∋_≈_ {i}{Δ}{a} a? b?
Env∋_≈⟨_⟩≈_ = λ {Δ}{Γ} a? i b? → Env∋_≈_ {i}{Δ}{Γ} a? b?
data NeVal∋_≈_ {i}{Δ} : {a : Ty}(a? b? : NeVal ∞ Δ a) → Set where
≈var : ∀{a}{x : Var Δ a} → NeVal∋ var x ≈ var x
≈app : ∀{a b}{n n' : NeVal ∞ Δ (a ⇒ b)} → NeVal∋ n ≈⟨ i ⟩≈ n' →
{v v' : Val ∞ Δ a} → Val∋ v ≈⟨ i ⟩≈ v' → NeVal∋ app n v ≈ app n' v'
data Env∋_≈_ {i}{Δ} : ∀{Γ} → Env ∞ Δ Γ → Env ∞ Δ Γ → Set where
≈ε : Env∋ ε ≈ ε
_≈,_ : ∀{Γ a}{ρ ρ' : Env ∞ Δ Γ} → Env∋ ρ ≈⟨ i ⟩≈ ρ' →
{v v' : Val ∞ Δ a} → Val∋ v ≈⟨ i ⟩≈ v' → Env∋ (ρ , v) ≈ (ρ' , v')
data Val∋_≈_ {i}{Δ} : {a : Ty}(a? b? : Val ∞ Δ a) → Set where
≈lam : ∀{Γ a b}{t : Tm (Γ , a) b}{ρ ρ' : Env ∞ Δ Γ} → Env∋ ρ ≈⟨ i ⟩≈ ρ' →
Val∋ lam t ρ ≈ lam t ρ'
≈ne : ∀{a}{n n' : NeVal ∞ Δ a} → NeVal∋ n ≈⟨ i ⟩≈ n' → Val∋ ne n ≈ ne n'
≈later : ∀ {a}{a∞ b∞ : ∞Val ∞ Δ a}(eq : ∞Val∋ a∞ ≈⟨ i ⟩≈ b∞) →
Val∋ later a∞ ≈ later b∞
record ∞Val∋_≈⟨_⟩≈_ {Δ a} (a∞ : ∞Val ∞ Δ a) i (b∞ : ∞Val ∞ Δ a) : Set where
coinductive
field
≈force : {j : Size< i} → Val∋ force a∞ ≈⟨ j ⟩≈ force b∞
∞Val∋_≈_ = λ {i}{Δ}{a} a? b? → ∞Val∋_≈⟨_⟩≈_ {Δ}{a} a? i b?
open ∞Val∋_≈⟨_⟩≈_ public
mutual
≈reflVal : ∀{i}{Δ}{a}(v : Val ∞ Δ a) → Val∋ v ≈⟨ i ⟩≈ v
≈reflVal {i} (ne n) = ≈ne (≈reflNeVal {i = i} n)
≈reflVal (lam t ρ) = ≈lam (≈reflEnv ρ)
≈reflVal (later v∞) = ≈later (∞≈reflVal v∞)
∞≈reflVal : ∀{i}{Δ}{a}(v : ∞Val ∞ Δ a) → ∞Val∋ v ≈⟨ i ⟩≈ v
≈force (∞≈reflVal v) = ≈reflVal (force v)
≈reflNeVal : ∀{i}{Δ}{a}(v : NeVal ∞ Δ a) → NeVal∋ v ≈⟨ i ⟩≈ v
≈reflNeVal (var x) = ≈var
≈reflNeVal (app v o) = ≈app (≈reflNeVal v) (≈reflVal o)
≈reflEnv : ∀{i}{Δ}{Γ}(e : Env ∞ Δ Γ) → Env∋ e ≈⟨ i ⟩≈ e
≈reflEnv ε = ≈ε
≈reflEnv (e , v) = ≈reflEnv e ≈, ≈reflVal v
mutual
≈symVal : ∀{i}{Δ}{a}{v v' : Val ∞ Δ a} → Val∋ v ≈⟨ i ⟩≈ v' →
Val∋ v' ≈⟨ i ⟩≈ v
≈symVal (≈lam p) = ≈lam (≈symEnv p )
≈symVal (≈ne p) = ≈ne (≈symNeVal p)
≈symVal (≈later p) = ≈later (∞≈symVal p)
∞≈symVal : ∀{i}{Δ}{a}{v v' : ∞Val ∞ Δ a} → ∞Val∋ v ≈⟨ i ⟩≈ v' →
∞Val∋ v' ≈⟨ i ⟩≈ v
≈force (∞≈symVal p) = ≈symVal (≈force p)
≈symNeVal : ∀{i}{Δ}{a}{v v' : NeVal ∞ Δ a} →
NeVal∋ v ≈⟨ i ⟩≈ v' → NeVal∋ v' ≈⟨ i ⟩≈ v
≈symNeVal ≈var = ≈var
≈symNeVal (≈app p q) = ≈app (≈symNeVal p) (≈symVal q)
≈symEnv : ∀{i}{Δ}{Γ}{e e' : Env ∞ Δ Γ} →
Env∋ e ≈⟨ i ⟩≈ e' → Env∋ e' ≈⟨ i ⟩≈ e
≈symEnv ≈ε = ≈ε
≈symEnv (p ≈, q) = ≈symEnv p ≈, ≈symVal q
mutual
≈transVal : ∀{i}{Δ}{a}{v v' v'' : Val ∞ Δ a} → Val∋ v ≈⟨ i ⟩≈ v' →
Val∋ v' ≈⟨ i ⟩≈ v'' → Val∋ v ≈⟨ i ⟩≈ v''
≈transVal (≈lam p) (≈lam p') = ≈lam (≈transEnv p p')
≈transVal (≈ne p) (≈ne p') = ≈ne (≈transNeVal p p')
≈transVal (≈later p) (≈later p') = ≈later (∞≈transVal p p')
∞≈transVal : ∀{i}{Δ}{a}{v v' v'' : ∞Val ∞ Δ a} → ∞Val∋ v ≈⟨ i ⟩≈ v' →
∞Val∋ v' ≈⟨ i ⟩≈ v'' → ∞Val∋ v ≈⟨ i ⟩≈ v''
≈force (∞≈transVal p q) = ≈transVal (≈force p) (≈force q)
≈transNeVal : ∀{i}{Δ}{a}{v v' v'' : NeVal ∞ Δ a} →
NeVal∋ v ≈⟨ i ⟩≈ v' → NeVal∋ v' ≈⟨ i ⟩≈ v'' →
NeVal∋ v ≈⟨ i ⟩≈ v''
≈transNeVal ≈var ≈var = ≈var
≈transNeVal (≈app p q) (≈app p' q') =
≈app (≈transNeVal p p' ) (≈transVal q q')
≈transEnv : ∀{i}{Δ}{a}{v v' v'' : Env ∞ Δ a} → Env∋ v ≈⟨ i ⟩≈ v' →
Env∋ v' ≈⟨ i ⟩≈ v'' → Env∋ v ≈⟨ i ⟩≈ v''
≈transEnv ≈ε ≈ε = ≈ε
≈transEnv (p ≈, q) (p' ≈, q') = (≈transEnv p p') ≈, ≈transVal q q'
≈Valsetoid : (i : Size)(Δ : Cxt)(a : Ty) → Setoid lzero lzero
≈Valsetoid i Δ a = record
{ Carrier = Val ∞ Δ a
; _≈_ = Val∋_≈_ {i}
; isEquivalence = record
{ refl = ≈reflVal _
; sym = ≈symVal
; trans = ≈transVal
}
}
module ≈Val-Reasoning {i : Size}{Δ : Cxt}{a : Ty} where
open SetoidReasoning (≈Valsetoid i Δ a) public