--
data ObjType:: *1 where
ArrT:: ObjType ~> ObjType ~> ObjType
IntT:: ObjType
data Rel:: ObjType ~> *0 ~> *0 where
IntR:: Rel IntT Int
IntTo:: Rel b s -> Rel (ArrT IntT b) (Int -> s)
-- First order functions only as constants
data Mode:: *1 where
Exp:: Mode
Val:: Mode
data E:: Mode ~> Row Tag ObjType ~> ObjType ~> *0 where
Const:: Rel a b -> b -> E Val env a
Var :: Label s -> E Val (RCons s t env) t
Shift:: E m env t -> E m (RCons s q env) t
Lam :: Label a -> E m (RCons a s env) t -> E Val env (ArrT s t)
App :: E m1 env (ArrT s t) -> E m2 env s -> E Exp env t
exp1 = Lam `f (Lam `y (App (Shift(Var `f)) (Var `y)))
int n = Const IntR n
oper x = Const (IntTo (IntTo IntR)) x
one = int 1
plus = oper (+)
-------------------------------------------------------
-- substitutions and substitute functions
data Sub:: Row Tag ObjType ~> Row Tag ObjType ~> *0 where
Id:: Sub r r
Bind:: Label t -> E m r2 x -> Sub r r2 -> Sub (RCons t x r) r2
Push:: Sub r1 r2 -> Sub (RCons a b r1) (RCons a b r2)
subst:: E m1 r t -> Sub r s -> exists m2 . E m2 s t
subst t Id = Ex t
subst (Const r c) sub = Ex (Const r c)
subst (Var v) (Bind u e r) = Ex e
subst (Var v) (Push sub) = Ex (Var v)
subst (Shift e) (Bind _ _ r) = subst e r
subst (Shift e) (Push sub) =
case subst e sub of {Ex a -> Ex(Shift a)}
subst (App f x) sub =
case (subst f sub,subst x sub) of
(Ex g,Ex y) -> Ex(App g y)
subst (Lam v x) sub =
case subst x (Push sub) of
(Ex body) -> Ex(Lam v body)
-----------------------------------------
-- Distingushing values from expressions
data Mode':: Mode ~> *0 where
Exp':: Mode' Exp
Val':: Mode' Val
mode :: E m e t -> Mode' m
mode (Lam v body) = Val'
mode (Var v) = Val'
mode (Const r v) = Val'
mode (Shift e) = mode e
mode (App _ _) = Exp'
type Closed = RNil
onestep :: E m Closed t -> (E Exp Closed t + E Val Closed t)
onestep (Var v) = unreachable
onestep (Shift e) = unreachable
onestep (Lam v body) = R (Lam v body)
onestep (Const r v) = R(Const r v)
onestep (App e1 e2) =
case (mode e1,mode e2) of
(Exp',_) ->
case onestep e1 of
L e -> L(App e e2)
R v -> L(App v e2)
(Val',Exp') ->
case onestep e2 of
L e -> L(App e1 e)
R v -> L(App e1 v)
(Val',Val') -> rule e1 e2
rule:: E Val Closed (ArrT a b) ->
E Val Closed a ->
(E Exp Closed b + E Val Closed b)
rule (Var _) _ = unreachable
rule (Shift _) _ = unreachable
rule (App _ _) _ = unreachable
rule (Lam x body) v =
let (Ex term) = subst body (Bind x v Id)
in case mode term of
Exp' -> L term
Val' -> R term
rule (Const IntR _) _ = unreachable
rule (Const (IntTo b) _) (Var _) = unreachable
rule (Const (IntTo b) _) (Shift _) = unreachable
rule (Const (IntTo b) _) (App _ _) = unreachable
rule (Const (IntTo b) f) (Lam x body) = unreachable
rule (Const (IntTo b) f) (Const (IntTo _) x) = unreachable
rule (Const (IntTo b) f) (Const IntR x) = R(Const b (f x))
------------------------------------------------
same :: Rel a b -> Rel a d -> Equal b d
same IntR IntR = Eq
same (IntTo y) (IntTo t) =
case (same y t) of
(Eq) -> Eq
same IntR (IntTo _) = unreachable
same (IntTo _) IntR = unreachable
----------------------------------------
mon = Monad return bind fail
where return x = R x
fail s = L s
bind (R x) f = f x
bind (L s) f = L s
monad mon
type M x = (String + x)
---------------------------------
data Rep:: ObjType ~> *0 where
I:: Rep IntT
Ar:: Rep a -> Rep b -> Rep (ArrT a b)
compareRep :: Rep a -> Rep b -> (String + Equal a b)
compareRep I I = R Eq
compareRep (Ar x y) (Ar s t) =
do { Eq <- compareRep x s
; Eq <- compareRep y t
; R Eq}
compareRep I (Ar x y) = L "I /= (Ar _ _)"
compareRep (Ar x y) I = L "(Ar _ _) /= I"
data Env:: Row Tag ObjType ~> *0 where
Enil:: Env RNil
Econs:: Label t -> (String,Rep x) -> Env e -> Env (RCons t x e)
deriving Record(e)
data Term:: *0 where
C:: Int -> Term
Ab:: String -> Rep a -> Term -> Term
Ap:: Term -> Term -> Term
V:: String -> Term
lookup:: String -> Env e -> (String + exists t m .(E m e t,Rep t))
lookup name Enil = fail ("Name not found: "++name)
lookup name {l=(s,t);rs}e | eqStr name s = R(Ex(Var l,t))
lookup name {l=(s,t);rs}e =
do { Ex(v,t) <- lookup name rs
; R(Ex(Shift v,t)) }
tc:: Term -> Env e -> (String + exists t m . (E m e t,Rep t))
tc (V s) env = lookup s env
tc (Ap f x) env =
do { Ex(f',ft) <- tc f env
; Ex(x',xt) <- tc x env
; case ft of
(Ar a b) ->
do { Eq <- compareRep a xt
; R(Ex(App f' x',b)) }
_ -> fail "Non fun in Ap" }
tc (Ab s t body) env =
do { let (HideLabel l) = newLabel s
; Ex(body',et) <- tc body {l=(s,t); env}e
; R(Ex(Lam l body',Ar t et)) }
tc (C n) env = R(Ex(Const IntR n,I))
good = Ab "f" (Ar I I) (Ab "x" I (Ap (V "f") (V "x")))
bad1 = Ab "f" (Ar I I) (Ab "x" I (Ap (V "g") (V "x")))
bad2 = Ab "f" (Ar I I) (Ab "x" I (Ap (V "x") (V "f")))
--