{-# OPTIONS --copatterns --sized-types #-}
module Terms where
open import Library
open import SizedInfiniteTypes
Cxt = List Ty
_≅C_ : Cxt → Cxt → Set
_≅C_ = ≅L _≅_
data Var : (Γ : Cxt) (a : Ty) → Set where
zero : ∀{Γ a} → Var (a ∷ Γ) a
suc : ∀{Γ a b} (x : Var Γ a) → Var (b ∷ Γ) a
v₀ : ∀ {a Γ} → Var (a ∷ Γ) a
v₀ = zero
data _≅V_ : ∀ {Γ Γ' a a'} → Var Γ a → Var Γ' a' → Set where
zero : ∀ {Γ a} {Γ' a'}
→ zero {Γ = Γ} {a} ≅V zero {Γ = Γ'} {a'}
suc : ∀ {Γ a b} {x : Var Γ a} {Γ' a' b'} {x' : Var Γ' a'}
→ x ≅V x'
→ suc {b = b} x ≅V suc {b = b'} x'
Vrefl : ∀ {Γ : Cxt} {a : Ty} {x : Var Γ a} → x ≅V x
Vrefl {x = zero} = zero
Vrefl {x = suc t} = suc Vrefl
Vsym : ∀ {Γ Γ' a a'} {x : Var Γ a} {x' : Var Γ' a'} → x ≅V x' → x' ≅V x
Vsym zero = zero
Vsym (suc [x]) = suc (Vsym [x])
Vtrans : ∀ {Γ Γ' Γ'' a a' a''} {x : Var Γ a} {x' : Var Γ' a'} {x'' : Var Γ'' a''}
→ x ≅V x' → x' ≅V x'' → x ≅V x''
Vtrans zero zero = zero
Vtrans (suc eq) (suc eq') = suc (Vtrans eq eq')
castVar : ∀{Γ Δ a b} (Γ≅Δ : Γ ≅C Δ) (a≅b : a ≅ b) (x : Var Γ a) → Var Δ b
castVar (a'≅b' ∷ Γ≅Δ) a≅b zero rewrite ≅-to-≡ (≅trans (≅sym a'≅b') a≅b) = zero
castVar (_ ∷ Γ≅Δ) a≅b (suc x) = suc (castVar Γ≅Δ a≅b x)
cohV : ∀{Γ Δ a b} (eqC : Γ ≅C Δ) (eq : a ≅ b) (x : Var Γ a) → castVar eqC eq x ≅V x
cohV (x∼y ∷ eqC) eq zero with ≅-to-≡ (≅trans (≅sym x∼y) eq)
cohV (x∼y ∷ eqC) eq zero | ≡.refl = zero
cohV (x∼y ∷ eqC) eq (suc x₁) = suc (cohV eqC eq x₁)
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
pair : ∀{a b} (t : Tm Γ a) (u : Tm Γ b) → Tm Γ (a ×̂ b)
fst : ∀{a b} (t : Tm Γ (a ×̂ b)) → Tm Γ a
snd : ∀{a b} (t : Tm Γ (a ×̂ b)) → Tm Γ b
▹_ : ∀{a∞} (t : Tm Γ (force a∞)) → Tm Γ (▸̂ a∞)
_∗_ : ∀{a : Ty}{b∞} (t : Tm Γ (▸̂ (delay a ⇒ b∞)))
(u : Tm Γ (▸ a)) → Tm Γ (▸̂ b∞)
data _≅T_ {Γ Γ' : Cxt} : {a a' : Ty} → Tm Γ a → Tm Γ' a' → Set where
var : ∀ {a a'}
→ {x : Var Γ a} {x' : Var Γ' a'} → ([x] : x ≅V x')
→ var x ≅T var x'
abs : ∀ {a b a' b'}
→ {t : Tm (a ∷ Γ) b} {t' : Tm (a' ∷ Γ') b'} → ([t] : t ≅T t')
→ abs t ≅T abs t'
app : ∀ {a b a' b'}
→ {t : Tm Γ (a →̂ b)} {t' : Tm Γ' (a' →̂ b')} → ([t] : t ≅T t')
→ {u : Tm Γ a} {u' : Tm Γ' a'} → ([u] : u ≅T u')
→ app t u ≅T app t' u'
pair : ∀ {a b a' b'}
→ {t : Tm Γ a} {t' : Tm Γ' a'} → ([t] : t ≅T t')
→ {u : Tm Γ b} {u' : Tm Γ' b'} → ([u] : u ≅T u')
→ pair t u ≅T pair t' u'
fst : ∀ {a b a' b'}
→ {t : Tm Γ (a ×̂ b)} {t' : Tm Γ' (a' ×̂ b')} → ([t] : t ≅T t')
→ fst t ≅T fst t'
snd : ∀ {a b a' b'}
→ {t : Tm Γ (a ×̂ b)} {t' : Tm Γ' (a' ×̂ b')} → ([t] : t ≅T t')
→ snd t ≅T snd t'
▹_ : ∀ {a∞ a∞'}
→ {t : Tm Γ (force a∞)} {t' : Tm Γ' (force a∞')} → ([t] : t ≅T t')
→ ▹_ {a∞ = a∞} t ≅T ▹_ {a∞ = a∞'} t'
_∗_ : ∀ {a : Ty}{b∞}{a' : Ty}{b∞'}
→ {t : Tm Γ (▸̂ (delay a ⇒ b∞ ))}
→ {t' : Tm Γ' (▸̂ (delay a' ⇒ b∞'))} → ([t] : t ≅T t')
→ {u : Tm Γ (▸ a)} {u' : Tm Γ' (▸ a')} → ([u] : u ≅T u')
→ (t ∗ u) ≅T (t' ∗ u')
Trefl : ∀ {Γ : Cxt} {a : Ty} → {t : Tm Γ a} → t ≅T t
Trefl {t = var x} = var Vrefl
Trefl {t = abs t} = abs Trefl
Trefl {t = app t u} = app Trefl Trefl
Trefl {t = ▹ t} = ▹ Trefl
Trefl {t = t ∗ u} = Trefl ∗ Trefl
Trefl {t = pair t u} = pair Trefl Trefl
Trefl {t = fst t} = fst Trefl
Trefl {t = snd t} = snd Trefl
Tsym : ∀ {Γ Γ' a a'} {t : Tm Γ a} {t' : Tm Γ' a'} → t ≅T t' → t' ≅T t
Tsym (var [x]) = var (Vsym [x])
Tsym (abs t) = abs (Tsym t)
Tsym (app t u) = app (Tsym t) (Tsym u)
Tsym (▹ t) = ▹ (Tsym t)
Tsym (t ∗ u) = (Tsym t) ∗ (Tsym u)
Tsym (pair t u) = pair (Tsym t) (Tsym u)
Tsym (fst t) = fst (Tsym t)
Tsym (snd t) = snd (Tsym t)
Ttrans : ∀ {Γ Γ' Γ'' a a' a''} {t : Tm Γ a} {t' : Tm Γ' a'} {t'' : Tm Γ'' a''}
→ t ≅T t' → t' ≅T t'' → t ≅T t''
Ttrans (var [x]) (var [x']) = var (Vtrans [x] [x'])
Ttrans (abs t) (abs t') = abs (Ttrans t t')
Ttrans (app t u) (app t' u') = app (Ttrans t t') (Ttrans u u')
Ttrans (▹ t) (▹ t') = ▹ (Ttrans t t')
Ttrans (t ∗ u) (t' ∗ u') = (Ttrans t t') ∗ (Ttrans u u')
Ttrans (pair t u) (pair t' u') = pair (Ttrans t t') (Ttrans u u')
Ttrans (fst t) (fst t') = fst (Ttrans t t')
Ttrans (snd t) (snd t') = snd (Ttrans t t')
castC : ∀{Γ Δ a b} (eqC : Γ ≅C Δ) (eq : a ≅ b) (t : Tm Γ a) → Tm Δ b
castC eqC eq (var x) = var (castVar eqC eq x)
castC eqC (eq →̂ eq₁) (abs t) = abs (castC (≅sym eq ∷ eqC) eq₁ t)
castC eqC eq (app t t₁) = app (castC eqC (≅refl →̂ eq) t) (castC eqC ≅refl t₁)
castC eqC (eq ×̂ eq₁) (pair t t₁) = pair (castC eqC eq t) (castC eqC eq₁ t₁)
castC eqC eq (fst t) = fst (castC eqC (eq ×̂ ≅refl) t)
castC eqC eq (snd t) = snd (castC eqC (≅refl ×̂ eq) t)
castC eqC (▸̂ a≅) (▹ t) = ▹ (castC eqC (≅force a≅) t)
castC eqC (▸̂ a≅) (t ∗ t₁) = (castC eqC (▸̂ (≅delay (≅refl →̂ (≅force a≅)))) t) ∗ (castC eqC ≅refl t₁)
cast : ∀{Γ a b} (eq : a ≅ b) (t : Tm Γ a) → Tm Γ b
cast = castC (≅L.refl ≅refl)
coh : ∀{Γ Δ a b} (eqC : Γ ≅C Δ) (eq : a ≅ b) (t : Tm Γ a) → castC eqC eq t ≅T t
coh eqC eq (var x) = var (cohV eqC eq x)
coh eqC (eq →̂ eq₁) (abs t) = abs (coh (≅sym eq ∷ eqC) eq₁ t)
coh eqC eq (app t t₁) = app (coh eqC (≅refl →̂ eq) t) (coh eqC ≅refl t₁)
coh eqC (eq ×̂ eq₁) (pair t t₁) = pair (coh eqC eq t) (coh eqC eq₁ t₁)
coh eqC eq (fst t) = fst (coh eqC (eq ×̂ ≅refl) t)
coh eqC eq (snd t) = snd (coh eqC (≅refl ×̂ eq) t)
coh eqC (▸̂ a≅) (▹ t) = ▹_ (coh eqC (≅force a≅) t)
coh eqC (▸̂ a≅) (t ∗ t₁) = coh eqC (▸̂ ≅delay (≅refl →̂ ≅force a≅)) t ∗ coh eqC ≅refl t₁
▹app : ∀{Γ c∞ b∞}{a : Ty} (eq : c∞ ∞≅ (delay a ⇒ b∞))
(t : Tm Γ (▸̂ c∞)) (u : Tm Γ (▸ a)) → Tm Γ (▸̂ b∞)
▹app eq t u = cast (▸̂ eq) t ∗ u
_∗'_ : ∀{Γ a∞ b∞} (t : Tm Γ (▸̂ (a∞ ⇒ b∞))) (u : Tm Γ (▸̂ a∞)) → Tm Γ (▸̂ b∞)
_∗'_ {a∞ = a∞} t u = _∗_ {a = force a∞} (cast (▸̂ (≅delay ≅refl)) t) (cast ((▸̂ (≅delay ≅refl))) u)
_<$>_ : ∀{Γ}{a : Ty}{b∞} (t : Tm Γ (a →̂ force b∞)) (u : Tm Γ (▸ a)) → Tm Γ (▸̂ b∞)
t <$> u = ▹ t ∗ u
tmId : ∀ {Γ} a → Tm Γ a → Tm Γ a
tmId a t = t
syntax tmId a t = t ∶ a
≡app₁ : ∀ {Γ a a' b}{t : Tm Γ (a →̂ b)}{t' : Tm Γ (a' →̂ b)}{u u'}
→ Tm.app t u ≡ app t' u'
→ (P : {a : Ty} → Tm Γ a → Set) → P t → P t'
≡app₁ ≡.refl P x = x
≡appTy : ∀{Γ a a' b}{t : Tm Γ (a →̂ b)}{t' : Tm Γ (a' →̂ b)}{u u'} → Tm.app t u ≡ app t' u' → a ≡ a'
≡appTy ≡.refl = ≡.refl
≡app₁' : ∀{Γ a b}{t t' : Tm Γ (a →̂ b)}{u u'} → Tm.app t u ≡ app t' u' → t ≡ t'
≡app₁' ≡.refl = ≡.refl