Files
newt/tests/Combinatory.newt

97 lines
3.4 KiB
Agda
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
module Combinatory
-- "A correct-by-construction conversion from lambda calculus to combinatory logic", Wouter Swierstra
data Unit : U where
MkUnit : Unit
infixr 7 _::_
data List : U -> U where
Nil : {A : U} -> List A
_::_ : {A : U} -> A -> List A -> List A
-- prj/menagerie/papers/combinatory
infixr 6 _~>_
data Type : U where
ι : Type
_~>_ : Type -> Type -> Type
A : U
A = Unit
Val : Type -> U
Val ι = A
Val (x ~> y) = Val x -> Val y
Ctx : U
Ctx = List Type
data Ref : Type -> Ctx -> U where
Here : {σ : Type} {Γ : Ctx} -> Ref σ (σ :: Γ)
There : {σ τ : Type} {Γ : Ctx} -> Ref σ Γ -> Ref σ (τ :: Γ)
data Term : Ctx -> Type -> U where
App : {Γ : Ctx} {σ τ : Type} -> Term Γ (σ ~> τ) -> Term Γ σ -> Term Γ τ
Lam : {Γ : Ctx} {σ τ : Type} -> Term (σ :: Γ) τ -> Term Γ (σ ~> τ)
Var : {Γ : Ctx} {σ : Type} -> Ref σ Γ Term Γ σ
infixr 7 _:::_
data Env : Ctx -> U where
ENil : Env Nil
_:::_ : {Γ : Ctx} {σ : Type} Val σ Env Γ Env (σ :: Γ)
-- TODO there is a problem here with coverage checking
-- I suspect something is being split before it's ready
-- lookup : {σ : Type} {Γ : Ctx} → Ref σ Γ → Env Γ → Val σ
-- lookup Here (x ::: y) = x
-- lookup (There i) (x ::: env) = lookup i env
lookup2 : {σ : Type} {Γ : Ctx} Env Γ Ref σ Γ Val σ
lookup2 (x ::: y) Here = x
lookup2 (x ::: env) (There i) = lookup2 env i
-- TODO MixFix - this was ⟦_⟧
eval : {Γ : Ctx} {σ : Type} Term Γ σ (Env Γ Val σ)
-- there was a unification error in direct application
eval (App t u) env = (eval t env) (eval u env)
eval (Lam t) env = \ x => eval t (x ::: env)
eval (Var i) env = lookup2 env i
data Comb : (Γ : Ctx) (u : Type) (Env Γ Val u) U where
S : {Γ : Ctx} {σ τ τ' : Type} Comb Γ ((σ ~> τ ~> τ') ~> (σ ~> τ) ~> (σ ~> τ')) (\ env => \ f g x => (f x) (g x))
K : {Γ : Ctx} {σ τ : Type} Comb Γ (σ ~> (τ ~> σ)) (\ env => \ x y => x)
I : {Γ : Ctx} {σ : Type} Comb Γ (σ ~> σ) (\ env => \ x => x)
B : {Γ : Ctx} {σ τ τ' : Type} Comb Γ ((τ ~> τ') ~> (σ ~> τ) ~> (σ ~> τ')) (\ env => \ f g x => f (g x))
C : {Γ : Ctx} {σ τ τ' : Type} Comb Γ ((σ ~> τ ~> τ') ~> τ ~> (σ ~> τ')) (\ env => \ f g x => (f x) g)
CVar : {Γ : Ctx} {σ : Type} (i : Ref σ Γ) Comb Γ σ (\ env => lookup2 env i)
CApp : {Γ : Ctx} {σ τ : Type} {f : _} {x : _} Comb Γ (σ ~> τ) f Comb Γ σ x Comb Γ τ (\ env => (f env) (x env))
sapp : {Γ : Ctx} {σ τ ρ : Type} {f : _} {x : _}
Comb Γ (σ ~> τ ~> ρ) f
Comb Γ (σ ~> τ) x
Comb Γ (σ ~> ρ) (\ env y => (f env y) (x env y))
sapp (CApp K t) I = t
sapp (CApp K t) (CApp K u) = CApp K (CApp t u)
-- was out of pattern because of unexpanded lets.
sapp (CApp K t) u = CApp (CApp B t) u
sapp t (CApp K u) = CApp (CApp C t) u
sapp t u = CApp (CApp S t) u
abs : {Γ : Ctx} {σ τ : Type} {f : _} Comb (σ :: Γ) τ f Comb Γ (σ ~> τ) (\ env x => f (x ::: env))
abs S = CApp K S
abs K = CApp K K
abs I = CApp K I
abs B = CApp K B
abs C = CApp K C
abs (CApp t u) = sapp (abs t) (abs u)
-- lookup2 was getting stuck, needed to re-eval the types in the rewritten env.
abs (CVar Here) = I
abs (CVar (There i)) = CApp K (CVar i)
translate : {Γ : Ctx} {σ : Type} (tm : Term Γ σ) Comb Γ σ (eval tm)
translate (App t u) = CApp (translate t) (translate u)
translate (Lam t) = abs (translate t)
translate (Var i) = CVar i