123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- {-
- A simple bidirectional type checker for simply typed lambda calculus which is
- sound by construction.
- -}
- module SimpleTypes where
- infix 10 _==_
- data _==_ {A : Set}(x : A) : A -> Set where
- refl : x == x
- data Maybe (A : Set) : Set where
- nothing : Maybe A
- just : A -> Maybe A
- data Nat : Set where
- zero : Nat
- suc : Nat -> Nat
- data Fin : Nat -> Set where
- fzero : {n : Nat} -> Fin (suc n)
- fsuc : {n : Nat} -> Fin n -> Fin (suc n)
- data List (A : Set) : Set where
- ε : List A
- _,_ : List A -> A -> List A
- length : forall {A} -> List A -> Nat
- length ε = zero
- length (xs , x) = suc (length xs)
- infixl 25 _,_
- -- Raw terms
- data Expr : Set where
- varʳ : Nat -> Expr
- _•ʳ_ : Expr -> Expr -> Expr
- ƛʳ_ : Expr -> Expr
- infixl 90 _•ʳ_
- infix 50 ƛʳ_
- -- Types
- data Type : Set where
- ι : Type
- _⟶_ : Type -> Type -> Type
- infixr 40 _⟶_
- -- Typed terms
- Ctx = List Type
- data Var : Ctx -> Type -> Set where
- vz : forall {Γ τ} -> Var (Γ , τ) τ
- vs : forall {Γ τ σ} -> Var Γ τ -> Var (Γ , σ) τ
- data Term : Ctx -> Type -> Set where
- var : forall {Γ τ} -> Var Γ τ -> Term Γ τ
- _•_ : forall {Γ τ σ} -> Term Γ (τ ⟶ σ) -> Term Γ τ -> Term Γ σ
- ƛ_ : forall {Γ τ σ} -> Term (Γ , σ) τ -> Term Γ (σ ⟶ τ)
- infixl 90 _•_
- infix 50 ƛ_
- -- Type erasure
- ⌊_⌋ˣ : forall {Γ τ} -> Var Γ τ -> Nat
- ⌊ vz ⌋ˣ = zero
- ⌊ vs x ⌋ˣ = suc ⌊ x ⌋ˣ
- ⌊_⌋ : forall {Γ τ} -> Term Γ τ -> Expr
- ⌊ var v ⌋ = varʳ ⌊ v ⌋ˣ
- ⌊ s • t ⌋ = ⌊ s ⌋ •ʳ ⌊ t ⌋
- ⌊ ƛ t ⌋ = ƛʳ ⌊ t ⌋
- -- Type equality
- infix 30 _≟_
- _≟_ : (σ τ : Type) -> Maybe (σ == τ)
- ι ≟ ι = just refl
- σ₁ ⟶ τ₁ ≟ σ₂ ⟶ τ₂ with σ₁ ≟ σ₂ | τ₁ ≟ τ₂
- σ ⟶ τ ≟ .σ ⟶ .τ | just refl | just refl = just refl
- _ ⟶ _ ≟ _ ⟶ _ | _ | _ = nothing
- _ ≟ _ = nothing
- -- The type checked view
- -- ok : forall {Γ τ e} -> Check ⌊ e ⌋ -- unsolved metas with no range!
- data Check (Γ : Ctx)(τ : Type) : Expr -> Set where
- ok : (t : Term Γ τ) -> Check Γ τ ⌊ t ⌋
- bad : {e : Expr} -> Check Γ τ e
- data Infer (Γ : Ctx) : Expr -> Set where
- yes : (τ : Type)(t : Term Γ τ) -> Infer Γ ⌊ t ⌋
- no : {e : Expr} -> Infer Γ e
- data Lookup (Γ : Ctx) : Nat -> Set where
- found : (τ : Type)(x : Var Γ τ) -> Lookup Γ ⌊ x ⌋ˣ
- outofscope : {n : Nat} -> Lookup Γ n
- lookup : (Γ : Ctx)(n : Nat) -> Lookup Γ n
- lookup ε n = outofscope
- lookup (Γ , τ) zero = found τ vz
- lookup (Γ , σ) (suc n) with lookup Γ n
- lookup (Γ , σ) (suc .(⌊ x ⌋ˣ)) | found τ x = found τ (vs x)
- lookup (Γ , σ) (suc n) | outofscope = outofscope
- infix 20 _⊢_∋_ _⊢_∈
- _⊢_∈ : (Γ : Ctx)(e : Expr) -> Infer Γ e
- _⊢_∋_ : (Γ : Ctx)(τ : Type)(e : Expr) -> Check Γ τ e
- Γ ⊢ ι ∋ ƛʳ e = bad
- Γ ⊢ (σ ⟶ τ) ∋ ƛʳ e with Γ , σ ⊢ τ ∋ e
- Γ ⊢ (σ ⟶ τ) ∋ ƛʳ .(⌊ t ⌋) | ok t = ok (ƛ t)
- Γ ⊢ (σ ⟶ τ) ∋ ƛʳ _ | bad = bad
- Γ ⊢ τ ∋ e with Γ ⊢ e ∈
- Γ ⊢ τ ∋ .(⌊ t ⌋) | yes σ t with τ ≟ σ
- Γ ⊢ τ ∋ .(⌊ t ⌋) | yes .τ t | just refl = ok t
- Γ ⊢ τ ∋ .(⌊ t ⌋) | yes σ t | nothing = bad
- Γ ⊢ τ ∋ e | no = bad
- Γ ⊢ varʳ i ∈ with lookup Γ i
- Γ ⊢ varʳ .(⌊ x ⌋ˣ) ∈ | found τ x = yes τ (var x)
- Γ ⊢ varʳ _ ∈ | outofscope = no
- Γ ⊢ e₁ •ʳ e₂ ∈ with Γ ⊢ e₁ ∈
- Γ ⊢ e₁ •ʳ e₂ ∈ | no = no
- Γ ⊢ .(⌊ t₁ ⌋) •ʳ e₂ ∈ | yes ι t₁ = no
- Γ ⊢ .(⌊ t₁ ⌋) •ʳ e₂ ∈ | yes (σ ⟶ τ) t₁ with Γ ⊢ σ ∋ e₂
- Γ ⊢ .(⌊ t₁ ⌋) •ʳ .(⌊ t₂ ⌋) ∈ | yes (σ ⟶ τ) t₁ | ok t₂ = yes τ (t₁ • t₂)
- Γ ⊢ .(⌊ t₁ ⌋) •ʳ _ ∈ | yes (σ ⟶ τ) t₁ | bad = no
- Γ ⊢ ƛʳ e ∈ = no
- -- Proving completeness (for normal terms)
- -- Needs magic with
- {-
- mutual
- data Nf : forall {Γ τ} -> Term Γ τ -> Set where
- ƛ-nf : forall {Γ σ τ} -> {t : Term (Γ , σ) τ} -> Nf t -> Nf (ƛ t)
- ne-nf : forall {Γ τ} -> {t : Term Γ τ} -> Ne t -> Nf t
- data Ne : forall {Γ τ} -> Term Γ τ -> Set where
- •-ne : forall {Γ σ τ} ->
- {t₁ : Term Γ (σ ⟶ τ)} -> Ne t₁ ->
- {t₂ : Term Γ σ} -> Nf t₂ -> Ne (t₁ • t₂)
- var-ne : forall {Γ τ} -> {x : Var Γ τ} -> Ne (var x)
- mutual
- complete-check : forall {Γ τ} -> (t : Term Γ τ) -> Nf t ->
- Γ ⊢ τ ∋ ⌊ t ⌋ == ok t
- complete-check ._ (ƛ-nf t) = {! !}
- complete-check _ (ne-nf n) with complete-infer _ n
- complete-check t (ne-nf n) | p = {! !}
- complete-infer : forall {Γ τ} -> (t : Term Γ τ) -> Ne t ->
- Γ ⊢ ⌊ t ⌋ ∈ == yes τ t
- complete-infer t ne = {! !}
- -}
- -- Testing
- test1 = ε ⊢ ι ⟶ ι ∋ ƛʳ varʳ zero
- test2 = ε , ι , ι ⟶ ι ⊢ varʳ zero •ʳ varʳ (suc zero) ∈
|