Files
newt/tests/Combinatory.newt

91 lines
3.3 KiB
Agda
Raw Permalink 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
-- prj/menagerie/papers/combinatory
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
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 (σ :: Γ)
lookup : {σ : Type} {Γ : Ctx} Ref σ Γ Env Γ Val σ
lookup Here (x ::: y) = x
lookup () ENil
lookup (There i) (x ::: env) = lookup i env
infixl 1 ⟦_⟧
⟦_⟧ : {Γ : Ctx} {σ : Type} Term Γ σ (Env Γ Val σ)
-- there was a unification error in direct application
App t u env = ( t env) ( u env)
Lam t env = \ x => t (x ::: env)
Var i env = lookup i env
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 => lookup i env)
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)
-- lookup 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)
-- Was a bug in pratt parser when argument `⟦ tm ⟧` had a prefix operator
translate : {Γ : Ctx} {σ : Type} (tm : Term Γ σ) Comb Γ σ tm
translate (App t u) = CApp (translate t) (translate u)
translate (Lam t) = abs (translate t)
translate (Var i) = CVar i