diff src/elab_env.sml @ 216:38b299373676

Looking up in a type class from a module
author Adam Chlipala <adamc@hcoop.net>
date Sat, 16 Aug 2008 15:58:25 -0400
parents 0343557355fc
children 56db662ebcfd
line wrap: on
line diff
--- a/src/elab_env.sml	Sat Aug 16 15:09:53 2008 -0400
+++ b/src/elab_env.sml	Sat Aug 16 15:58:25 2008 -0400
@@ -31,7 +31,6 @@
 
 structure U = ElabUtil
 
-structure IS = IntBinarySet
 structure IM = IntBinaryMap
 structure SM = BinaryMapFn(struct
                            type ord_key = string
@@ -96,6 +95,11 @@
          ClNamed of int
        | ClProj of int * string list * string
 
+fun cn2s cn =
+    case cn of
+        ClNamed n => "Named(" ^ Int.toString n ^ ")"
+      | ClProj (m, ms, x) => "Proj(" ^ Int.toString m ^ "," ^ String.concatWith "," ms ^ "," ^ x ^ ")"
+
 structure CK = struct
 type ord_key = class_name
 open Order
@@ -118,6 +122,14 @@
        | CkRel of int
        | CkProj of int * string list * string
 
+fun ck2s ck =
+    case ck of
+        CkNamed n => "Named(" ^ Int.toString n ^ ")"
+      | CkRel n => "Rel(" ^ Int.toString n ^ ")"
+      | CkProj (m, ms, x) => "Proj(" ^ Int.toString m ^ "," ^ String.concatWith "," ms ^ "," ^ x ^ ")"
+
+fun cp2s (cn, ck) = "(" ^ cn2s cn ^ "," ^ ck2s ck ^ ")"
+
 structure KK = struct
 type ord_key = class_key
 open Order
@@ -147,6 +159,11 @@
     ground = KM.empty
 }
 
+fun printClasses cs = CM.appi (fn (cn, {ground = km}) =>
+                                  (print (cn2s cn ^ ":");
+                                   KM.appi (fn (ck, _) => print (" " ^ ck2s ck)) km;
+                                   print "\n")) cs
+
 type env = {
      renameC : kind var' SM.map,
      relC : (string * kind) list,
@@ -515,6 +532,20 @@
 fun lookupStr (env : env) x = SM.find (#renameStr env, x)
 
 
+fun sgiSeek (sgi, (sgns, strs, cons)) =
+    case sgi of
+        SgiConAbs (x, n, _) => (sgns, strs, IM.insert (cons, n, x))
+      | SgiCon (x, n, _, _) => (sgns, strs, IM.insert (cons, n, x))
+      | SgiDatatype (x, n, _, _) => (sgns, strs, IM.insert (cons, n, x))
+      | SgiDatatypeImp (x, n, _, _, _, _, _) => (sgns, strs, IM.insert (cons, n, x))
+      | SgiVal _ => (sgns, strs, cons)
+      | SgiSgn (x, n, _) => (IM.insert (sgns, n, x), strs, cons)
+      | SgiStr (x, n, _) => (sgns, IM.insert (strs, n, x), cons)
+      | SgiConstraint _ => (sgns, strs, cons)
+      | SgiTable _ => (sgns, strs, cons)
+      | SgiClassAbs (x, n) => (sgns, strs, IM.insert (cons, n, x))
+      | SgiClass (x, n, _) => (sgns, strs, IM.insert (cons, n, x))
+
 fun sgnSeek f sgis =
     let
         fun seek (sgis, sgns, strs, cons) =
@@ -533,18 +564,11 @@
                         SOME (v, (sgns, strs, cons))
                     end
                   | NONE =>
-                    case sgi of
-                        SgiConAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x))
-                      | SgiCon (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x))
-                      | SgiDatatype (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x))
-                      | SgiDatatypeImp (x, n, _, _, _, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x))
-                      | SgiVal _ => seek (sgis, sgns, strs, cons)
-                      | SgiSgn (x, n, _) => seek (sgis, IM.insert (sgns, n, x), strs, cons)
-                      | SgiStr (x, n, _) => seek (sgis, sgns, IM.insert (strs, n, x), cons)
-                      | SgiConstraint _ => seek (sgis, sgns, strs, cons)
-                      | SgiTable _ => seek (sgis, sgns, strs, cons)
-                      | SgiClassAbs (x, n) => seek (sgis, sgns, strs, IM.insert (cons, n, x))
-                      | SgiClass (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x))
+                    let
+                        val (sgns, strs, cons) = sgiSeek (sgi, (sgns, strs, cons))
+                    in
+                        seek (sgis, sgns, strs, cons)
+                    end
     in
         seek (sgis, IM.empty, IM.empty, IM.empty)
     end
@@ -584,6 +608,18 @@
              end)
       | _ => c
 
+fun sgnS_con' (m1, ms', (sgns, strs, cons)) c =
+    case c of
+        CModProj (m1, ms, x) =>
+        (case IM.find (strs, m1) of
+             NONE => c
+           | SOME m1x => CModProj (m1, ms' @ m1x :: ms, x))
+      | CNamed n =>
+        (case IM.find (cons, n) of
+             NONE => c
+           | SOME nx => CModProj (m1, ms', nx))
+      | _ => c
+
 fun sgnS_sgn (str, (sgns, strs, cons)) sgn =
     case sgn of
         SgnProj (m1, ms, x) =>
@@ -664,21 +700,44 @@
     case #1 (hnormSgn env sgn) of
         SgnConst sgis =>
         let
-            val (classes, _) =
-                foldl (fn (sgi, (classes, newClasses)) =>
+            val (classes, _, _) =
+                foldl (fn (sgi, (classes, newClasses, fmap)) =>
                           let
                               fun found (x, n) =
                                   (CM.insert (classes,
                                               ClProj (m1, ms, x),
                                               empty_class),
-                                   IS.add (newClasses, n))
+                                   IM.insert (newClasses, n, x),
+                                   sgiSeek (#1 sgi, fmap))
+
+                              fun default () = (classes, newClasses, sgiSeek (#1 sgi, fmap))
                           in
                               case #1 sgi of
                                   SgiClassAbs xn => found xn
                                 | SgiClass (x, n, _) => found (x, n)
-                                | _ => (classes, newClasses)
+                                | SgiVal (x, n, (CApp ((CNamed f, _), a), _)) =>
+                                  (case IM.find (newClasses, f) of
+                                       NONE => default ()
+                                     | SOME fx =>
+                                       case class_key_in (sgnS_con' (m1, ms, fmap) (#1 a), #2 a) of
+                                           NONE => default ()
+                                         | SOME ck =>
+                                           let
+                                               val cn = ClProj (m1, ms, fx)
+                                               val class = Option.getOpt (CM.find (classes, cn), empty_class)
+                                               val class = {
+                                                   ground = KM.insert (#ground class, ck,
+                                                                       (EModProj (m1, ms, x), #2 sgn))
+                                               }
+
+                                           in
+                                               (CM.insert (classes, cn, class),
+                                                newClasses,
+                                                fmap)
+                                           end)
+                                | _ => default ()
                           end)
-                (classes, IS.empty) sgis
+                (classes, IM.empty, (IM.empty, IM.empty, IM.empty)) sgis
         in
             classes
         end
@@ -803,6 +862,14 @@
                               SOME ((KType, #2 sgn), SOME (CModProj (m1, ms, x'), #2 sgn))
                           else
                               NONE
+                        | SgiClassAbs (x, _) => if x = field then
+                                                    SOME ((KArrow ((KType, #2 sgn), (KType, #2 sgn)), #2 sgn), NONE)
+                                                else
+                                                    NONE
+                        | SgiClass (x, _, c) => if x = field then
+                                                    SOME ((KArrow ((KType, #2 sgn), (KType, #2 sgn)), #2 sgn), SOME c)
+                                                else
+                                                    NONE
                         | _ => NONE) sgis of
              NONE => NONE
            | SOME ((k, co), subs) => SOME (k, Option.map (sgnSubCon (str, subs)) co))