{-# OPTIONS --allow-unsolved-meta #-}
data ℕ : Set where
zero : ℕ
succ : ℕ → ℕ
data Ty : Set where
* : Ty
_⇒_ : Ty → Ty → Ty
⟦_⟧ : Ty → Set
⟦ * ⟧ = ℕ
⟦ τ ⇒ τ' ⟧ = ⟦ τ ⟧ → ⟦ τ' ⟧
data Cxt : Set where
ε : Cxt
_,_ : Cxt → Ty → Cxt
data _∈_ : Ty → Cxt → Set where
here : {Γ : Cxt} {τ : Ty} → τ ∈ (Γ , τ)
there : {Γ : Cxt} {τ τ' : Ty} → τ ∈ Γ → τ ∈ (Γ , τ')
data Term : Cxt → Ty → Set where
Z : {Γ : Cxt} → Term Γ *
S : {Γ : Cxt} → Term Γ (* ⇒ *)
var : {Γ : Cxt} {τ : Ty} → τ ∈ Γ → Term Γ τ
app : {Γ : Cxt} {τ τ' : Ty} → Term Γ (τ ⇒ τ') → Term Γ τ → Term Γ τ'
abs : {Γ : Cxt} {τ τ' : Ty} → Term (Γ , τ) τ' → Term Γ (τ ⇒ τ')
data Env : Cxt → Set where
∅ : Env ε
_∷ʳ_ : {Γ : Cxt} {τ : Ty} → Env Γ → ⟦ τ ⟧ → Env (Γ , τ)
lookup : {Γ : Cxt} {τ : Ty} → Env Γ → τ ∈ Γ → ⟦ τ ⟧
lookup (Γ ∷ʳ x) here = x
lookup (Γ ∷ʳ x) (there p) = lookup Γ p
eval : {Γ : Cxt} {τ : Ty} → Env Γ → Term Γ τ → ⟦ τ ⟧
eval env Z = zero
eval env S = succ
eval env (var v) = lookup env v
eval env (app f x) = (eval env f) (eval env x)
eval env (abs t) = λ x → eval (env ∷ʳ x) t
I : Term ε (* ⇒ *)
I = abs (var here)
open import Padova2024.EquationalReasoning
_ : eval ∅ I ≡ (λ x → x)
_ = refl
K : Term ε (* ⇒ (* ⇒ *))
K = abs (abs (var (there here)))
_ : eval ∅ (app S (app S (app S Z))) ≡ succ (succ (succ zero))
_ = refl