--
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"))) --