changeset 624:354800878b4d

Kind polymorphism through Explify
author Adam Chlipala <adamc@hcoop.net>
date Sun, 22 Feb 2009 16:32:56 -0500
parents 588b9d16b00a
children 47947d6e9750
files src/elab_print.sml src/expl.sml src/expl_env.sig src/expl_env.sml src/expl_print.sig src/expl_print.sml src/expl_util.sig src/expl_util.sml src/explify.sml
diffstat 9 files changed, 243 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/src/elab_print.sml	Sun Feb 22 16:10:25 2009 -0500
+++ b/src/elab_print.sml	Sun Feb 22 16:32:56 2009 -0500
@@ -68,7 +68,7 @@
                             space,
                             p_kind (E.pushKRel env x) k]
 
-and p_kind k = p_kind' false k
+and p_kind env = p_kind' false env
 
 fun p_explicitness e =
     case e of
--- a/src/expl.sml	Sun Feb 22 16:10:25 2009 -0500
+++ b/src/expl.sml	Sun Feb 22 16:32:56 2009 -0500
@@ -37,6 +37,9 @@
        | KTuple of kind list
        | KRecord of kind
 
+       | KRel of int
+       | KFun of string * kind
+
 withtype kind = kind' located
 
 datatype con' =
@@ -50,6 +53,10 @@
        | CApp of con * con
        | CAbs of string * kind * con
 
+       | CKAbs of string * con
+       | CKApp of con * kind
+       | TKFun of string * con
+
        | CName of string
 
        | CRecord of kind * (con * con) list
@@ -88,6 +95,9 @@
        | ECApp of exp * con
        | ECAbs of string * kind * exp
 
+       | EKAbs of string * exp
+       | EKApp of exp * kind
+
        | ERecord of (con * exp * con) list
        | EField of exp * con * { field : con, rest : con }
        | EConcat of exp * con * exp * con
--- a/src/expl_env.sig	Sun Feb 22 16:10:25 2009 -0500
+++ b/src/expl_env.sig	Sun Feb 22 16:32:56 2009 -0500
@@ -42,6 +42,9 @@
            | Rel of int * 'a
            | Named of int * 'a
 
+    val pushKRel : env -> string -> env
+    val lookupKRel : env -> int -> string
+
     val pushCRel : env -> string -> Expl.kind -> env
     val lookupCRel : env -> int -> string * Expl.kind
 
--- a/src/expl_env.sml	Sun Feb 22 16:10:25 2009 -0500
+++ b/src/expl_env.sml	Sun Feb 22 16:32:56 2009 -0500
@@ -45,8 +45,32 @@
 
 exception SynUnif
 
+val liftKindInKind =
+    U.Kind.mapB {kind = fn bound => fn k =>
+                                       case k of
+                                           KRel xn =>
+                                           if xn < bound then
+                                               k
+                                           else
+                                               KRel (xn + 1)
+                                         | _ => k,
+                 bind = fn (bound, _) => bound + 1}
+
+val liftKindInCon =
+    U.Con.mapB {kind = fn bound => fn k =>
+                                      case k of
+                                          KRel xn =>
+                                          if xn < bound then
+                                              k
+                                          else
+                                              KRel (xn + 1)
+                                        | _ => k,
+                con = fn _ => fn c => c,
+                bind = fn (bound, U.Con.RelK _) => bound + 1
+                        | (bound, _) => bound}
+
 val liftConInCon =
-    U.Con.mapB {kind = fn k => k,
+    U.Con.mapB {kind = fn _ => fn k => k,
                 con = fn bound => fn c =>
                                      case c of
                                          CRel xn =>
@@ -56,7 +80,7 @@
                                              CRel (xn + 1)
                                        (*| CUnif _ => raise SynUnif*)
                                        | _ => c,
-                bind = fn (bound, U.Con.Rel _) => bound + 1
+                bind = fn (bound, U.Con.RelC _) => bound + 1
                         | (bound, _) => bound}
 
 val lift = liftConInCon 0
@@ -74,77 +98,82 @@
        | Named of int * 'a
 
 type env = {
-     renameC : kind var' SM.map,
+     relK : string list,
+
      relC : (string * kind) list,
      namedC : (string * kind * con option) IM.map,
 
-     renameE : con var' SM.map,
      relE : (string * con) list,
      namedE : (string * con) IM.map,
 
-     renameSgn : (int * sgn) SM.map,
      sgn : (string * sgn) IM.map,
 
-     renameStr : (int * sgn) SM.map,
      str : (string * sgn) IM.map
 }
 
 val namedCounter = ref 0
 
 val empty = {
-    renameC = SM.empty,
+    relK = [],
+
     relC = [],
     namedC = IM.empty,
 
-    renameE = SM.empty,
     relE = [],
     namedE = IM.empty,
 
-    renameSgn = SM.empty,
     sgn = IM.empty,
 
-    renameStr = SM.empty,
     str = IM.empty
 }
 
+fun pushKRel (env : env) x =
+    {relK = x :: #relK env,
+
+     relC = map (fn (x, k) => (x, liftKindInKind 0 k)) (#relC env),
+     namedC = #namedC env,
+
+     relE = map (fn (x, c) => (x, liftKindInCon 0 c)) (#relE env),
+     namedE = #namedE env,
+
+     sgn = #sgn env,
+
+     str = #str env
+    }
+
+fun lookupKRel (env : env) n =
+    (List.nth (#relK env, n))
+    handle Subscript => raise UnboundRel n
+
 fun pushCRel (env : env) x k =
-    let
-        val renameC = SM.map (fn Rel' (n, k) => Rel' (n+1, k)
-                               | x => x) (#renameC env)
-    in
-        {renameC = SM.insert (renameC, x, Rel' (0, k)),
-         relC = (x, k) :: #relC env,
-         namedC = IM.map (fn (x, k, co) => (x, k, Option.map lift co)) (#namedC env),
+    {relK = #relK env,
 
-         renameE = #renameE env,
-         relE = map (fn (x, c) => (x, lift c)) (#relE env),
-         namedE = IM.map (fn (x, c) => (x, lift c)) (#namedE env),
+     relC = (x, k) :: #relC env,
+     namedC = IM.map (fn (x, k, co) => (x, k, Option.map lift co)) (#namedC env),
 
-         renameSgn = #renameSgn env,
-         sgn = #sgn env,
+     relE = map (fn (x, c) => (x, lift c)) (#relE env),
+     namedE = IM.map (fn (x, c) => (x, lift c)) (#namedE env),
 
-         renameStr = #renameStr env,
-         str = #str env
-        }
-    end
+     sgn = #sgn env,
+
+     str = #str env
+    }
 
 fun lookupCRel (env : env) n =
     (List.nth (#relC env, n))
     handle Subscript => raise UnboundRel n
 
 fun pushCNamed (env : env) x n k co =
-    {renameC = SM.insert (#renameC env, x, Named' (n, k)),
+    {relK = #relK env,
+
      relC = #relC env,
      namedC = IM.insert (#namedC env, n, (x, k, co)),
 
-     renameE = #renameE env,
      relE = #relE env,
      namedE = #namedE env,
 
-     renameSgn = #renameSgn env,
      sgn = #sgn env,
      
-     renameStr = #renameStr env,
      str = #str env}
 
 fun lookupCNamed (env : env) n =
@@ -153,42 +182,33 @@
       | SOME x => x
 
 fun pushERel (env : env) x t =
-    let
-        val renameE = SM.map (fn Rel' (n, t) => Rel' (n+1, t)
-                               | x => x) (#renameE env)
-    in
-        {renameC = #renameC env,
-         relC = #relC env,
-         namedC = #namedC env,
+    {relK = #relK env,
 
-         renameE = SM.insert (renameE, x, Rel' (0, t)),
-         relE = (x, t) :: #relE env,
-         namedE = #namedE env,
+     relC = #relC env,
+     namedC = #namedC env,
 
-         renameSgn = #renameSgn env,
-         sgn = #sgn env,
+     relE = (x, t) :: #relE env,
+     namedE = #namedE env,
 
-         renameStr = #renameStr env,
-         str = #str env}
-    end
+     sgn = #sgn env,
+
+     str = #str env}
 
 fun lookupERel (env : env) n =
     (List.nth (#relE env, n))
     handle Subscript => raise UnboundRel n
 
 fun pushENamed (env : env) x n t =
-    {renameC = #renameC env,
+    {relK = #relK env,
+
      relC = #relC env,
      namedC = #namedC env,
 
-     renameE = SM.insert (#renameE env, x, Named' (n, t)),
      relE = #relE env,
      namedE = IM.insert (#namedE env, n, (x, t)),
 
-     renameSgn = #renameSgn env,
      sgn = #sgn env,
      
-     renameStr = #renameStr env,
      str = #str env}
 
 fun lookupENamed (env : env) n =
@@ -197,18 +217,16 @@
       | SOME x => x
 
 fun pushSgnNamed (env : env) x n sgis =
-    {renameC = #renameC env,
+    {relK = #relK env,
+
      relC = #relC env,
      namedC = #namedC env,
 
-     renameE = #renameE env,
      relE = #relE env,
      namedE = #namedE env,
 
-     renameSgn = SM.insert (#renameSgn env, x, (n, sgis)),
      sgn = IM.insert (#sgn env, n, (x, sgis)),
      
-     renameStr = #renameStr env,
      str = #str env}
 
 fun lookupSgnNamed (env : env) n =
@@ -217,18 +235,16 @@
       | SOME x => x
 
 fun pushStrNamed (env : env) x n sgis =
-    {renameC = #renameC env,
+    {relK = #relK env,
+
      relC = #relC env,
      namedC = #namedC env,
 
-     renameE = #renameE env,
      relE = #relE env,
      namedE = #namedE env,
 
-     renameSgn = #renameSgn env,
      sgn = #sgn env,
 
-     renameStr = SM.insert (#renameStr env, x, (n, sgis)),
      str = IM.insert (#str env, n, (x, sgis))}
 
 fun lookupStrNamed (env : env) n =
--- a/src/expl_print.sig	Sun Feb 22 16:10:25 2009 -0500
+++ b/src/expl_print.sig	Sun Feb 22 16:32:56 2009 -0500
@@ -26,7 +26,7 @@
  *)
 
 signature EXPL_PRINT = sig
-    val p_kind : Expl.kind Print.printer
+    val p_kind : ExplEnv.env -> Expl.kind Print.printer
     val p_con : ExplEnv.env -> Expl.con Print.printer
     val p_exp : ExplEnv.env -> Expl.exp Print.printer
     val p_decl : ExplEnv.env -> Expl.decl Print.printer
--- a/src/expl_print.sml	Sun Feb 22 16:10:25 2009 -0500
+++ b/src/expl_print.sml	Sun Feb 22 16:32:56 2009 -0500
@@ -38,22 +38,33 @@
 
 val debug = ref false
 
-fun p_kind' par (k, _) =
+fun p_kind' par env (k, _) =
     case k of
         KType => string "Type"
-      | KArrow (k1, k2) => parenIf par (box [p_kind' true k1,
+      | KArrow (k1, k2) => parenIf par (box [p_kind' true env k1,
                                              space,
                                              string "->",
                                              space,
-                                             p_kind k2])
+                                             p_kind env k2])
       | KName => string "Name"
-      | KRecord k => box [string "{", p_kind k, string "}"]
+      | KRecord k => box [string "{", p_kind env k, string "}"]
       | KUnit => string "Unit"
       | KTuple ks => box [string "(",
-                          p_list_sep (box [space, string "*", space]) p_kind ks,
+                          p_list_sep (box [space, string "*", space]) (p_kind env) ks,
                           string ")"]
 
-and p_kind k = p_kind' false k
+      | KRel n => ((if !debug then
+                         string (E.lookupKRel env n ^ "_" ^ Int.toString n)
+                     else
+                         string (E.lookupKRel env n))
+                    handle E.UnboundRel _ => string ("UNBOUND_REL" ^ Int.toString n))
+      | KFun (x, k) => box [string x,
+                            space,
+                            string "-->",
+                            space,
+                            p_kind (E.pushKRel env x) k]
+
+and p_kind env = p_kind' false env
 
 fun p_con' par env (c, _) =
     case c of
@@ -66,7 +77,7 @@
                                              space,
                                              string "::",
                                              space,
-                                             p_kind k,
+                                             p_kind env k,
                                              space,
                                              string "->",
                                              space,
@@ -116,7 +127,7 @@
                                             space,
                                             string "::",
                                             space,
-                                            p_kind k,
+                                            p_kind env k,
                                             space,
                                             string "=>",
                                             space,
@@ -134,7 +145,7 @@
                                               space,
                                               p_con env c]) xcs,
                               string "]::",
-                              p_kind k])
+                              p_kind env k])
         else
             parenIf par (box [string "[",
                               p_list (fn (x, c) =>
@@ -158,6 +169,21 @@
       | CProj (c, n) => box [p_con env c,
                              string ".",
                              string (Int.toString n)]
+
+      | CKAbs (x, c) => box [string x,
+                             space,
+                             string "==>",
+                             space,
+                             p_con (E.pushKRel env x) c]
+      | CKApp (c, k) => box [p_con env c,
+                             string "[[",
+                             p_kind env k,
+                             string "]]"]
+      | TKFun (x, c) => box [string x,
+                             space,
+                             string "-->",
+                             space,
+                             p_con (E.pushKRel env x) c]
         
 and p_con env = p_con' false env
 
@@ -261,7 +287,7 @@
                                              space,
                                              string "::",
                                              space,
-                                             p_kind k,
+                                             p_kind env k,
                                              space,
                                              string "=>",
                                              space,
@@ -397,6 +423,15 @@
                                     newline,
                                     p_exp (E.pushERel env x t) e2]
 
+      | EKAbs (x, e) => box [string x,
+                             space,
+                             string "==>",
+                             space,
+                             p_exp (E.pushKRel env x) e]
+      | EKApp (e, k) => box [p_exp env e,
+                             string "[[",
+                             p_kind env k,
+                             string "]]"]
                                     
 
 and p_exp env = p_exp' false env
@@ -438,14 +473,14 @@
                                     space,
                                     string "::",
                                     space,
-                                    p_kind k]
+                                    p_kind env k]
       | SgiCon (x, n, k, c) => box [string "con",
                                     space,
                                     p_named x n,
                                     space,
                                     string "::",
                                     space,
-                                    p_kind k,
+                                    p_kind env k,
                                     space,
                                     string "=",
                                     space,
@@ -559,7 +594,7 @@
                                   space,
                                   string "::",
                                   space,
-                                  p_kind k,
+                                  p_kind env k,
                                   space,
                                   string "=",
                                   space,
--- a/src/expl_util.sig	Sun Feb 22 16:10:25 2009 -0500
+++ b/src/expl_util.sig	Sun Feb 22 16:32:56 2009 -0500
@@ -28,17 +28,24 @@
 signature EXPL_UTIL = sig
 
 structure Kind : sig
+    val mapfoldB : {kind : ('context, Expl.kind', 'state, 'abort) Search.mapfolderB,
+                    bind : 'context * string -> 'context}
+                   -> ('context, Expl.kind, 'state, 'abort) Search.mapfolderB
     val mapfold : (Expl.kind', 'state, 'abort) Search.mapfolder
                   -> (Expl.kind, 'state, 'abort) Search.mapfolder
     val exists : (Expl.kind' -> bool) -> Expl.kind -> bool
+    val mapB : {kind : 'context -> Expl.kind' -> Expl.kind',
+                bind : 'context * string -> 'context}
+               -> 'context -> (Expl.kind -> Expl.kind)
 end
 
 structure Con : sig
     datatype binder =
-             Rel of string * Expl.kind
-           | Named of string * Expl.kind
+             RelK of string
+           | RelC of string * Expl.kind
+           | NamedC of string * Expl.kind
 
-    val mapfoldB : {kind : (Expl.kind', 'state, 'abort) Search.mapfolder,
+    val mapfoldB : {kind : ('context, Expl.kind', 'state, 'abort) Search.mapfolderB,
                     con : ('context, Expl.con', 'state, 'abort) Search.mapfolderB,
                     bind : 'context * binder -> 'context}
                    -> ('context, Expl.con, 'state, 'abort) Search.mapfolderB
@@ -46,7 +53,7 @@
                    con : (Expl.con', 'state, 'abort) Search.mapfolder}
                   -> (Expl.con, 'state, 'abort) Search.mapfolder
 
-    val mapB : {kind : Expl.kind' -> Expl.kind',
+    val mapB : {kind : 'context -> Expl.kind' -> Expl.kind',
                 con : 'context -> Expl.con' -> Expl.con',
                 bind : 'context * binder -> 'context}
                -> 'context -> (Expl.con -> Expl.con)
@@ -59,12 +66,13 @@
 
 structure Exp : sig
     datatype binder =
-             RelC of string * Expl.kind
+             RelK of string
+           | RelC of string * Expl.kind
            | NamedC of string * Expl.kind
            | RelE of string * Expl.con
            | NamedE of string * Expl.con
 
-    val mapfoldB : {kind : (Expl.kind', 'state, 'abort) Search.mapfolder,
+    val mapfoldB : {kind : ('context, Expl.kind', 'state, 'abort) Search.mapfolderB,
                     con : ('context, Expl.con', 'state, 'abort) Search.mapfolderB,
                     exp : ('context, Expl.exp', 'state, 'abort) Search.mapfolderB,
                     bind : 'context * binder -> 'context}
@@ -80,12 +88,13 @@
 
 structure Sgn : sig
     datatype binder =
-             RelC of string * Expl.kind
+             RelK of string
+           | RelC of string * Expl.kind
            | NamedC of string * Expl.kind
            | Sgn of string * Expl.sgn
            | Str of string * Expl.sgn
 
-    val mapfoldB : {kind : (Expl.kind', 'state, 'abort) Search.mapfolder,
+    val mapfoldB : {kind : ('context, Expl.kind', 'state, 'abort) Search.mapfolderB,
                     con : ('context, Expl.con', 'state, 'abort) Search.mapfolderB,
                     sgn_item : ('context, Expl.sgn_item', 'state, 'abort) Search.mapfolderB,
                     sgn : ('context, Expl.sgn', 'state, 'abort) Search.mapfolderB,
--- a/src/expl_util.sml	Sun Feb 22 16:10:25 2009 -0500
+++ b/src/expl_util.sml	Sun Feb 22 16:32:56 2009 -0500
@@ -33,39 +33,55 @@
 
 structure Kind = struct
 
-fun mapfold f =
+fun mapfoldB {kind, bind} =
     let
-        fun mfk k acc =
-            S.bindP (mfk' k acc, f)
+        fun mfk ctx k acc =
+            S.bindP (mfk' ctx k acc, kind ctx)
 
-        and mfk' (kAll as (k, loc)) =
+        and mfk' ctx (kAll as (k, loc)) =
             case k of
                 KType => S.return2 kAll
 
               | KArrow (k1, k2) =>
-                S.bind2 (mfk k1,
+                S.bind2 (mfk ctx k1,
                       fn k1' =>
-                         S.map2 (mfk k2,
+                         S.map2 (mfk ctx k2,
                               fn k2' =>
                                  (KArrow (k1', k2'), loc)))
 
               | KName => S.return2 kAll
 
               | KRecord k =>
-                S.map2 (mfk k,
+                S.map2 (mfk ctx k,
                         fn k' =>
                            (KRecord k', loc))
 
               | KUnit => S.return2 kAll
 
               | KTuple ks =>
-                S.map2 (ListUtil.mapfold mfk ks,
+                S.map2 (ListUtil.mapfold (mfk ctx) ks,
                         fn ks' =>
                            (KTuple ks', loc))
+
+              | KRel _ => S.return2 kAll
+              | KFun (x, k) =>
+                S.map2 (mfk (bind (ctx, x)) k,
+                        fn k' =>
+                           (KFun (x, k'), loc))
     in
         mfk
     end
 
+fun mapfold fk =
+    mapfoldB {kind = fn () => fk,
+              bind = fn ((), _) => ()} ()
+
+fun mapB {kind, bind} ctx k =
+    case mapfoldB {kind = fn ctx => fn k => fn () => S.Continue (kind ctx k, ()),
+                   bind = bind} ctx k () of
+        S.Continue (k, ()) => k
+      | S.Return _ => raise Fail "ExplUtil.Kind.mapB: Impossible"
+
 fun exists f k =
     case mapfold (fn k => fn () =>
                              if f k then
@@ -80,12 +96,13 @@
 structure Con = struct
 
 datatype binder =
-         Rel of string * Expl.kind
-       | Named of string * Expl.kind
+         RelK of string
+       | RelC of string * Expl.kind
+       | NamedC of string * Expl.kind
 
 fun mapfoldB {kind = fk, con = fc, bind} =
     let
-        val mfk = Kind.mapfold fk
+        val mfk = Kind.mapfoldB {kind = fk, bind = fn (ctx, x) => bind (ctx, RelK x)}
 
         fun mfc ctx c acc =
             S.bindP (mfc' ctx c acc, fc ctx)
@@ -99,9 +116,9 @@
                               fn c2' =>
                                  (TFun (c1', c2'), loc)))
               | TCFun (x, k, c) =>
-                S.bind2 (mfk k,
+                S.bind2 (mfk ctx k,
                       fn k' =>
-                         S.map2 (mfc (bind (ctx, Rel (x, k))) c,
+                         S.map2 (mfc (bind (ctx, RelC (x, k))) c,
                               fn c' =>
                                  (TCFun (x, k', c'), loc)))
               | TRecord c =>
@@ -119,16 +136,16 @@
                               fn c2' =>
                                  (CApp (c1', c2'), loc)))
               | CAbs (x, k, c) =>
-                S.bind2 (mfk k,
+                S.bind2 (mfk ctx k,
                       fn k' =>
-                         S.map2 (mfc (bind (ctx, Rel (x, k))) c,
+                         S.map2 (mfc (bind (ctx, RelC (x, k))) c,
                               fn c' =>
                                  (CAbs (x, k', c'), loc)))
 
               | CName _ => S.return2 cAll
 
               | CRecord (k, xcs) =>
-                S.bind2 (mfk k,
+                S.bind2 (mfk ctx k,
                       fn k' =>
                          S.map2 (ListUtil.mapfold (fn (x, c) =>
                                                       S.bind2 (mfc ctx x,
@@ -146,9 +163,9 @@
                               fn c2' =>
                                  (CConcat (c1', c2'), loc)))
               | CMap (k1, k2) =>
-                S.bind2 (mfk k1,
+                S.bind2 (mfk ctx k1,
                          fn k1' =>
-                            S.map2 (mfk k2,
+                            S.map2 (mfk ctx k2,
                                     fn k2' =>
                                        (CMap (k1', k2'), loc)))
 
@@ -163,17 +180,32 @@
                 S.map2 (mfc ctx c,
                         fn c' =>
                            (CProj (c', n), loc))
+
+              | CKAbs (x, c) =>
+                S.map2 (mfc (bind (ctx, RelK x)) c,
+                        fn c' =>
+                           (CKAbs (x, c'), loc))
+              | CKApp (c, k) =>
+                S.bind2 (mfc ctx c,
+                      fn c' =>
+                         S.map2 (mfk ctx k,
+                                 fn k' =>
+                                    (CKApp (c', k'), loc)))
+              | TKFun (x, c) =>
+                S.map2 (mfc (bind (ctx, RelK x)) c,
+                        fn c' =>
+                           (TKFun (x, c'), loc))
     in
         mfc
     end
 
 fun mapfold {kind = fk, con = fc} =
-    mapfoldB {kind = fk,
+    mapfoldB {kind = fn () => fk,
               con = fn () => fc,
               bind = fn ((), _) => ()} ()
 
 fun mapB {kind, con, bind} ctx c =
-    case mapfoldB {kind = fn k => fn () => S.Continue (kind k, ()),
+    case mapfoldB {kind = fn ctx => fn k => fn () => S.Continue (kind ctx k, ()),
                    con = fn ctx => fn c => fn () => S.Continue (con ctx c, ()),
                    bind = bind} ctx c () of
         S.Continue (c, ()) => c
@@ -204,20 +236,22 @@
 structure Exp = struct
 
 datatype binder =
-         RelC of string * Expl.kind
+         RelK of string
+       | RelC of string * Expl.kind
        | NamedC of string * Expl.kind
        | RelE of string * Expl.con
        | NamedE of string * Expl.con
 
 fun mapfoldB {kind = fk, con = fc, exp = fe, bind} =
     let
-        val mfk = Kind.mapfold fk
+        val mfk = Kind.mapfoldB {kind = fk, bind = fn (ctx, x) => bind (ctx, RelK x)}
 
         fun bind' (ctx, b) =
             let
                 val b' = case b of
-                             Con.Rel x => RelC x
-                           | Con.Named x => NamedC x
+                             Con.RelK x => RelK x
+                           | Con.RelC x => RelC x
+                           | Con.NamedC x => NamedC x
             in
                 bind (ctx, b')
             end
@@ -254,7 +288,7 @@
                               fn c' =>
                                  (ECApp (e', c'), loc)))
               | ECAbs (x, k, e) =>
-                S.bind2 (mfk k,
+                S.bind2 (mfk ctx k,
                       fn k' =>
                          S.map2 (mfe (bind (ctx, RelC (x, k))) e,
                               fn e' =>
@@ -338,12 +372,23 @@
                                      S.map2 (mfe (bind (ctx, RelE (x, t))) e2,
                                           fn e2' =>
                                              (ELet (x, t', e1', e2'), loc))))
+
+              | EKAbs (x, e) =>
+                S.map2 (mfe (bind (ctx, RelK x)) e,
+                        fn e' =>
+                           (EKAbs (x, e'), loc))
+              | EKApp (e, k) =>
+                S.bind2 (mfe ctx e,
+                        fn e' =>
+                           S.map2 (mfk ctx k,
+                                   fn k' =>
+                                      (EKApp (e', k'), loc)))
     in
         mfe
     end
 
 fun mapfold {kind = fk, con = fc, exp = fe} =
-    mapfoldB {kind = fk,
+    mapfoldB {kind = fn () => fk,
               con = fn () => fc,
               exp = fn () => fe,
               bind = fn ((), _) => ()} ()
@@ -372,7 +417,8 @@
 structure Sgn = struct
 
 datatype binder =
-         RelC of string * Expl.kind
+         RelK of string
+       | RelC of string * Expl.kind
        | NamedC of string * Expl.kind
        | Str of string * Expl.sgn
        | Sgn of string * Expl.sgn
@@ -382,14 +428,15 @@
         fun bind' (ctx, b) =
             let
                 val b' = case b of
-                             Con.Rel x => RelC x
-                           | Con.Named x => NamedC x
+                             Con.RelK x => RelK x
+                           | Con.RelC x => RelC x
+                           | Con.NamedC x => NamedC x
             in
                 bind (ctx, b')
             end
         val con = Con.mapfoldB {kind = kind, con = con, bind = bind'}
 
-        val kind = Kind.mapfold kind
+        val kind = Kind.mapfoldB {kind = kind, bind = fn (ctx, x) => bind (ctx, RelK x)}
 
         fun sgi ctx si acc =
             S.bindP (sgi' ctx si acc, sgn_item ctx)
@@ -397,11 +444,11 @@
         and sgi' ctx (siAll as (si, loc)) =
             case si of
                 SgiConAbs (x, n, k) =>
-                S.map2 (kind k,
+                S.map2 (kind ctx k,
                      fn k' =>
                         (SgiConAbs (x, n, k'), loc))
               | SgiCon (x, n, k, c) =>
-                S.bind2 (kind k,
+                S.bind2 (kind ctx k,
                      fn k' =>
                         S.map2 (con ctx c,
                              fn c' =>
@@ -482,7 +529,7 @@
     end
 
 fun mapfold {kind, con, sgn_item, sgn} =
-    mapfoldB {kind = kind,
+    mapfoldB {kind = fn () => kind,
               con = fn () => con,
               sgn_item = fn () => sgn_item,
               sgn = fn () => sgn,
--- a/src/explify.sml	Sun Feb 22 16:10:25 2009 -0500
+++ b/src/explify.sml	Sun Feb 22 16:32:56 2009 -0500
@@ -45,6 +45,9 @@
       | L.KUnif (_, _, ref (SOME k)) => explifyKind k
       | L.KUnif _ => raise Fail ("explifyKind: KUnif at " ^ EM.spanToString loc)
 
+      | L.KRel n => (L'.KRel n, loc)
+      | L.KFun (x, k) => (L'.KFun (x, explifyKind k), loc)
+
 fun explifyCon (c, loc) =
     case c of
         L.TFun (t1, t2) => (L'.TFun (explifyCon t1, explifyCon t2), loc)
@@ -74,6 +77,10 @@
       | L.CUnif (_, _, _, ref (SOME c)) => explifyCon c
       | L.CUnif _ => raise Fail ("explifyCon: CUnif at " ^ EM.spanToString loc)
 
+      | L.CKAbs (x, c) => (L'.CKAbs (x, explifyCon c), loc)
+      | L.CKApp (c, k) => (L'.CKApp (explifyCon c, explifyKind k), loc)
+      | L.TKFun (x, c) => (L'.TKFun (x, explifyCon c), loc)
+
 fun explifyPatCon pc =
     case pc of
         L.PConVar n => L'.PConVar n
@@ -123,6 +130,9 @@
                     | L.EDVal (x, t, e') => (L'.ELet (x, explifyCon t, explifyExp e', e), loc))
         (explifyExp e) des
 
+      | L.EKAbs (x, e) => (L'.EKAbs (x, explifyExp e), loc)
+      | L.EKApp (e, k) => (L'.EKApp (explifyExp e, explifyKind k), loc)
+
 fun explifySgi (sgi, loc) =
     case sgi of
         L.SgiConAbs (x, n, k) => SOME (L'.SgiConAbs (x, n, explifyKind k), loc)