comparison src/elab_env.sml @ 711:7292bcb7c02d

Made type class system very general; demo compiles
author Adam Chlipala <adamc@hcoop.net>
date Thu, 09 Apr 2009 12:31:56 -0400
parents d8217b4cb617
children f152f215a02c
comparison
equal deleted inserted replaced
710:71409a4ccb67 711:7292bcb7c02d
160 160
161 datatype class_name = 161 datatype class_name =
162 ClNamed of int 162 ClNamed of int
163 | ClProj of int * string list * string 163 | ClProj of int * string list * string
164 164
165 fun class_name_out cn =
166 case cn of
167 ClNamed n => (CNamed n, ErrorMsg.dummySpan)
168 | ClProj x => (CModProj x, ErrorMsg.dummySpan)
169
165 fun cn2s cn = 170 fun cn2s cn =
166 case cn of 171 case cn of
167 ClNamed n => "Named(" ^ Int.toString n ^ ")" 172 ClNamed n => "Named(" ^ Int.toString n ^ ")"
168 | ClProj (m, ms, x) => "Proj(" ^ Int.toString m ^ "," ^ String.concatWith "," ms ^ "," ^ x ^ ")" 173 | ClProj (m, ms, x) => "Proj(" ^ Int.toString m ^ "," ^ String.concatWith "," ms ^ "," ^ x ^ ")"
169 174
183 end 188 end
184 189
185 structure CS = BinarySetFn(CK) 190 structure CS = BinarySetFn(CK)
186 structure CM = BinaryMapFn(CK) 191 structure CM = BinaryMapFn(CK)
187 192
188 datatype class_key = 193 type class = {ground : (con * exp) list,
189 CkNamed of int 194 rules : (int * con list * con * exp) list}
190 | CkRel of int 195 val empty_class = {ground = [],
191 | CkProj of int * string list * string 196 rules = []}
192 | CkApp of class_key * class_key
193 | CkOther of con
194
195 fun ck2s ck =
196 case ck of
197 CkNamed n => "Named(" ^ Int.toString n ^ ")"
198 | CkRel n => "Rel(" ^ Int.toString n ^ ")"
199 | CkProj (m, ms, x) => "Proj(" ^ Int.toString m ^ "," ^ String.concatWith "," ms ^ "," ^ x ^ ")"
200 | CkApp (ck1, ck2) => "App(" ^ ck2s ck1 ^ ", " ^ ck2s ck2 ^ ")"
201 | CkOther _ => "Other"
202
203 type class_key_n = class_key * int
204
205 fun ckn2s (ck, n) = ck2s ck ^ "[" ^ Int.toString n ^ "]"
206
207 fun cp2s (cn, ck) = "(" ^ cn2s cn ^ "," ^ ck2s ck ^ ")"
208
209 structure KK = struct
210 type ord_key = class_key_n
211 open Order
212 fun compare' x =
213 case x of
214 (CkNamed n1, CkNamed n2) => Int.compare (n1, n2)
215 | (CkNamed _, _) => LESS
216 | (_, CkNamed _) => GREATER
217
218 | (CkRel n1, CkRel n2) => Int.compare (n1, n2)
219 | (CkRel _, _) => LESS
220 | (_, CkRel _) => GREATER
221
222 | (CkProj (m1, ms1, x1), CkProj (m2, ms2, x2)) =>
223 join (Int.compare (m1, m2),
224 fn () => join (joinL String.compare (ms1, ms2),
225 fn () => String.compare (x1, x2)))
226 | (CkProj _, _) => LESS
227 | (_, CkProj _) => GREATER
228
229 | (CkApp (f1, x1), CkApp (f2, x2)) =>
230 join (compare' (f1, f2),
231 fn () => compare' (x1, x2))
232 | (CkApp _, _) => LESS
233 | (_, CkApp _) => GREATER
234
235 | (CkOther _, CkOther _) => EQUAL
236 fun compare ((k1, n1), (k2, n2)) =
237 join (Int.compare (n1, n2),
238 fn () => compare' (k1, k2))
239 end
240
241 structure KM = BinaryMapFn(KK)
242
243 type class = {ground : ((class_name * class_key) list * exp) KM.map,
244 inclusions : exp CM.map}
245 val empty_class = {ground = KM.empty,
246 inclusions = CM.empty}
247
248 fun printClasses cs = (print "Classes:\n";
249 CM.appi (fn (cn, {ground = km, ...} : class) =>
250 (print (cn2s cn ^ ":");
251 KM.appi (fn (ck, _) => print (" " ^ ckn2s ck)) km;
252 print "\n")) cs)
253 197
254 type env = { 198 type env = {
255 renameK : int SM.map, 199 renameK : int SM.map,
256 relK : string list, 200 relK : string list,
257 201
306 sgn = IM.empty, 250 sgn = IM.empty,
307 251
308 renameStr = SM.empty, 252 renameStr = SM.empty,
309 str = IM.empty 253 str = IM.empty
310 } 254 }
311
312 fun liftClassKey' ck =
313 case ck of
314 CkNamed _ => ck
315 | CkRel n => CkRel (n + 1)
316 | CkProj _ => ck
317 | CkApp (ck1, ck2) => CkApp (liftClassKey' ck1, liftClassKey' ck2)
318 | CkOther c => CkOther (lift c)
319
320 fun liftClassKey (ck, n) = (liftClassKey' ck, n)
321 255
322 fun pushKRel (env : env) x = 256 fun pushKRel (env : env) x =
323 let 257 let
324 val renameK = SM.map (fn n => n+1) (#renameK env) 258 val renameK = SM.map (fn n => n+1) (#renameK env)
325 in 259 in
332 namedC = #namedC env, 266 namedC = #namedC env,
333 267
334 datatypes = #datatypes env, 268 datatypes = #datatypes env,
335 constructors = #constructors env, 269 constructors = #constructors env,
336 270
337 classes = #classes env, 271 classes = CM.map (fn cl => {ground = map (fn (c, e) =>
272 (liftKindInCon 0 c,
273 e))
274 (#ground cl),
275 rules = #rules cl})
276 (#classes env),
338 277
339 renameE = SM.map (fn Rel' (n, c) => Rel' (n, liftKindInCon 0 c) 278 renameE = SM.map (fn Rel' (n, c) => Rel' (n, liftKindInCon 0 c)
340 | Named' (n, c) => Named' (n, c)) (#renameE env), 279 | Named' (n, c) => Named' (n, c)) (#renameE env),
341 relE = map (fn (x, c) => (x, liftKindInCon 0 c)) (#relE env), 280 relE = map (fn (x, c) => (x, liftKindInCon 0 c)) (#relE env),
342 namedE = #namedE env, 281 namedE = #namedE env,
369 308
370 datatypes = #datatypes env, 309 datatypes = #datatypes env,
371 constructors = #constructors env, 310 constructors = #constructors env,
372 311
373 classes = CM.map (fn class => 312 classes = CM.map (fn class =>
374 {ground = KM.foldli (fn (ck, e, km) => 313 {ground = map (fn (c, e) =>
375 KM.insert (km, liftClassKey ck, e)) 314 (liftConInCon 0 c,
376 KM.empty (#ground class), 315 e))
377 inclusions = #inclusions class}) 316 (#ground class),
317 rules = #rules class})
378 (#classes env), 318 (#classes env),
379 319
380 renameE = SM.map (fn Rel' (n, c) => Rel' (n, lift c) 320 renameE = SM.map (fn Rel' (n, c) => Rel' (n, lift c)
381 | Named' (n, c) => Named' (n, c)) (#renameE env), 321 | Named' (n, c) => Named' (n, c)) (#renameE env),
382 relE = map (fn (x, c) => (x, lift c)) (#relE env), 322 relE = map (fn (x, c) => (x, lift c)) (#relE env),
480 fun lookupConstructor (env : env) s = SM.find (#constructors env, s) 420 fun lookupConstructor (env : env) s = SM.find (#constructors env, s)
481 421
482 fun datatypeArgs (xs, _) = xs 422 fun datatypeArgs (xs, _) = xs
483 fun constructors (_, dt) = IM.foldri (fn (n, (x, to), ls) => (x, n, to) :: ls) [] dt 423 fun constructors (_, dt) = IM.foldri (fn (n, (x, to), ls) => (x, n, to) :: ls) [] dt
484 424
425 fun listClasses (env : env) =
426 map (fn (cn, {ground, rules}) =>
427 (class_name_out cn,
428 ground
429 @ map (fn (nvs, cs, c, e) =>
430 let
431 val loc = #2 c
432 val c = foldr (fn (c', c) => (TFun (c', c), loc)) c cs
433 val c = ListUtil.foldli (fn (n, (), c) => (TCFun (Explicit,
434 "x" ^ Int.toString n,
435 (KError, loc),
436 c), loc))
437 c (List.tabulate (nvs, fn _ => ()))
438 in
439 (c, e)
440 end) rules)) (CM.listItemsi (#classes env))
441
485 fun pushClass (env : env) n = 442 fun pushClass (env : env) n =
486 {renameK = #renameK env, 443 {renameK = #renameK env,
487 relK = #relK env, 444 relK = #relK env,
488 445
489 renameC = #renameC env, 446 renameC = #renameC env,
518 | find (SOME c) = Option.isSome (CM.find (#classes env, c)) 475 | find (SOME c) = Option.isSome (CM.find (#classes env, c))
519 in 476 in
520 find (class_name_in c) 477 find (class_name_in c)
521 end 478 end
522 479
523 fun class_key_in (all as (c, _)) = 480 fun class_head_in c =
524 case c of 481 case #1 c of
525 CRel n => CkRel n 482 CApp (f, _) => class_head_in f
526 | CNamed n => CkNamed n 483 | CUnif (_, _, _, ref (SOME c)) => class_head_in c
527 | CModProj x => CkProj x 484 | _ => class_name_in c
528 | CUnif (_, _, _, ref (SOME c)) => class_key_in c 485
529 | CApp (c1, c2) => CkApp (class_key_in c1, class_key_in c2) 486 exception Unify
530 | _ => CkOther all 487
531 488 fun unifyKinds (k1, k2) =
532 fun class_key_out loc = 489 case (#1 k1, #1 k2) of
533 let 490 (KType, KType) => ()
534 fun cko k = 491 | (KArrow (d1, r1), KArrow (d2, r2)) => (unifyKinds (d1, d2); unifyKinds (r1, r2))
535 case k of 492 | (KName, KName) => ()
536 CkRel n => (CRel n, loc) 493 | (KRecord k1, KRecord k2) => unifyKinds (k1, k2)
537 | CkNamed n => (CNamed n, loc) 494 | (KUnit, KUnit) => ()
538 | CkProj x => (CModProj x, loc) 495 | (KTuple ks1, KTuple ks2) => (ListPair.appEq unifyKinds (ks1, ks2)
539 | CkApp (k1, k2) => (CApp (cko k1, cko k2), loc) 496 handle ListPair.UnequalLengths => raise Unify)
540 | CkOther c => c 497 | (KUnif (_, _, ref (SOME k1)), _) => unifyKinds (k1, k2)
541 in 498 | (_, KUnif (_, _, ref (SOME k2))) => unifyKinds (k1, k2)
542 cko 499 | (KRel n1, KRel n2) => if n1 = n2 then () else raise Unify
543 end 500 | (KFun (_, k1), KFun (_, k2)) => unifyKinds (k1, k2)
544 501 | _ => raise Unify
545 fun class_pair_in (c, _) = 502
546 case c of 503 fun unifyCons rs =
547 CApp (f, x) => 504 let
548 (case class_name_in f of 505 fun unify d (c1, c2) =
549 SOME f => SOME (f, class_key_in x) 506 case (#1 c1, #1 c2) of
550 | _ => NONE) 507 (CUnif (_, _, _, ref (SOME c1)), _) => unify d (c1, c2)
551 | CUnif (_, _, _, ref (SOME c)) => class_pair_in c 508 | (_, CUnif (_, _, _, ref (SOME c2))) => unify d (c1, c2)
552 | _ => NONE 509
553 510 | (c1', CRel n2) =>
554 fun sub_class_key (n, c) = 511 if n2 < d then
555 let 512 case c1' of
556 fun csk k = 513 CRel n1 => if n1 = n2 then () else raise Unify
557 case k of 514 | _ => raise Unify
558 CkRel n' => SOME (if n' = n then 515 else if n2 - d >= length rs then
559 c 516 case c1' of
560 else 517 CRel n1 => if n1 = n2 - length rs then () else raise Unify
561 k) 518 | _ => raise Unify
562 | CkNamed _ => SOME k 519 else
563 | CkProj _ => SOME k 520 let
564 | CkApp (k1, k2) => 521 val r = List.nth (rs, n2 - d)
565 (case (csk k1, csk k2) of 522 in
566 (SOME k1, SOME k2) => SOME (CkApp (k1, k2)) 523 case !r of
567 | _ => NONE) 524 NONE => r := SOME c1
568 | CkOther _ => NONE 525 | SOME c2 => unify d (c1, c2)
569 in 526 end
570 csk 527
571 end 528 | (TFun (d1, r1), TFun (d2, r2)) => (unify d (d1, d2); unify d (r1, r2))
572 529 | (TCFun (_, _, k1, r1), TCFun (_, _, k2, r2)) => (unifyKinds (k1, k2); unify (d + 1) (r1, r2))
573 fun resolveClass (env : env) c = 530 | (TRecord c1, TRecord c2) => unify d (c1, c2)
574 let 531 | (TDisjoint (a1, b1, c1), TDisjoint (a2, b2, c2)) =>
575 fun doPair (f, x) = 532 (unify d (a1, a2); unify d (b1, b2); unify d (c1, c2))
576 case CM.find (#classes env, f) of 533
577 NONE => NONE 534 | (CNamed n1, CNamed n2) => if n1 = n2 then () else raise Unify
578 | SOME class => 535 | (CModProj (n1, ms1, x1), CModProj (n2, ms2, x2)) =>
579 let 536 if n1 = n2 andalso ms1 = ms2 andalso x1 = x2 then () else raise Unify
580 val loc = #2 c 537 | (CApp (f1, x1), CApp (f2, x2)) => (unify d (f1, f2); unify d (x1, x2))
581 538 | (CAbs (_, k1, b1), CAbs (_, k2, b2)) => (unifyKinds (k1, k2); unify (d + 1) (b1, b2))
582 fun tryIncs () = 539
540 | (CKAbs (_, b1), CKAbs (_, b2)) => unify d (b1, b2)
541 | (CKApp (c1, k1), CKApp (c2, k2)) => (unify d (c1, c2); unifyKinds (k1, k2))
542 | (TKFun (_, c1), TKFun (_, c2)) => unify d (c1, c2)
543
544 | (CName s1, CName s2) => if s1 = s2 then () else raise Unify
545
546 | (CRecord (k1, xcs1), CRecord (k2, xcs2)) =>
547 (unifyKinds (k1, k2);
548 ListPair.appEq (fn ((x1, c1), (x2, c2)) => (unify d (x1, x2); unify d (c1, c2))) (xcs1, xcs2)
549 handle ListPair.UnequalLengths => raise Unify)
550 | (CConcat (f1, x1), CConcat (f2, x2)) => (unify d (f1, f2); unify d (x1, x2))
551 | (CMap (d1, r1), CMap (d2, r2)) => (unifyKinds (d1, d2); unifyKinds (r1, r2))
552
553 | (CUnit, CUnit) => ()
554
555 | (CTuple cs1, CTuple cs2) => (ListPair.appEq (unify d) (cs1, cs2)
556 handle ListPair.UnequalLengths => raise Unify)
557 | (CProj (c1, n1), CProj (c2, n2)) => (unify d (c1, c2);
558 if n1 = n2 then () else raise Unify)
559
560 | _ => raise Unify
561 in
562 unify
563 end
564
565 fun tryUnify nRs (c1, c2) =
566 let
567 val rs = List.tabulate (nRs, fn _ => ref NONE)
568 in
569 (unifyCons rs 0 (c1, c2);
570 SOME (map (fn r => case !r of
571 NONE => raise Unify
572 | SOME c => c) rs))
573 handle Unify => NONE
574 end
575
576 fun unifySubst (rs : con list) =
577 U.Con.mapB {kind = fn _ => fn k => k,
578 con = fn d => fn c =>
579 case c of
580 CRel n =>
581 if n < d then
582 c
583 else
584 #1 (List.nth (rs, n - d))
585 | _ => c,
586 bind = fn (d, U.Con.RelC _) => d + 1
587 | (d, _) => d}
588 0
589
590 fun resolveClass (env : env) =
591 let
592 fun resolve c =
593 let
594 fun doHead f =
595 case CM.find (#classes env, f) of
596 NONE => NONE
597 | SOME class =>
583 let 598 let
584 fun tryIncs fs = 599 val loc = #2 c
585 case fs of 600
601 fun tryRules rules =
602 case rules of
586 [] => NONE 603 [] => NONE
587 | (f', e') :: fs => 604 | (nRs, cs, c', e) :: rules' =>
588 case doPair (f', x) of 605 case tryUnify nRs (c, c') of
589 NONE => tryIncs fs 606 NONE => tryRules rules'
590 | SOME e => 607 | SOME rs =>
591 let 608 let
592 val e' = (ECApp (e', class_key_out loc x), loc) 609 val eos = map (resolve o unifySubst rs) cs
593 val e' = (EApp (e', e), loc)
594 in 610 in
595 SOME e' 611 if List.exists (not o Option.isSome) eos then
612 tryRules rules'
613 else
614 let
615 val es = List.mapPartial (fn x => x) eos
616
617 val e = foldr (fn (c, e) => (ECApp (e, c), loc)) e rs
618 val e = foldl (fn (e', e) => (EApp (e, e'), loc)) e es
619 in
620 SOME e
621 end
596 end 622 end
623
624 fun rules () = tryRules (#rules class)
625
626 fun tryGrounds ces =
627 case ces of
628 [] => rules ()
629 | (c', e) :: ces' =>
630 case tryUnify 0 (c, c') of
631 NONE => tryGrounds ces'
632 | SOME _ => SOME e
597 in 633 in
598 tryIncs (CM.listItemsi (#inclusions class)) 634 tryGrounds (#ground class)
599 end 635 end
600 636 in
601 fun tryRules (k, args) = 637 case class_head_in c of
602 let 638 SOME f => doHead f
603 val len = length args 639 | _ => NONE
604 640 end
605 fun tryNext () = 641 in
606 case k of 642 resolve
607 CkApp (k1, k2) => tryRules (k1, k2 :: args)
608 | _ => tryIncs ()
609 in
610 case KM.find (#ground class, (k, length args)) of
611 SOME (cs, e) =>
612 let
613 val es = map (fn (cn, ck) =>
614 let
615 val ck = ListUtil.foldli (fn (i, arg, ck) =>
616 case ck of
617 NONE => NONE
618 | SOME ck =>
619 sub_class_key (len - i - 1,
620 arg)
621 ck)
622 (SOME ck) args
623 in
624 case ck of
625 NONE => NONE
626 | SOME ck => doPair (cn, ck)
627 end) cs
628 in
629 if List.exists (not o Option.isSome) es then
630 tryNext ()
631 else
632 let
633 val e = foldl (fn (arg, e) => (ECApp (e, class_key_out loc arg), loc))
634 e args
635 val e = foldr (fn (pf, e) => (EApp (e, pf), loc))
636 e (List.mapPartial (fn x => x) es)
637 in
638 SOME e
639 end
640 end
641 | NONE => tryNext ()
642 end
643 in
644 tryRules (x, [])
645 end
646 in
647 case class_pair_in c of
648 SOME p => doPair p
649 | _ => NONE
650 end 643 end
651 644
652 fun pushERel (env : env) x t = 645 fun pushERel (env : env) x t =
653 let 646 let
654 val renameE = SM.map (fn Rel' (n, t) => Rel' (n+1, t) 647 val renameE = SM.map (fn Rel' (n, t) => Rel' (n+1, t)
655 | x => x) (#renameE env) 648 | x => x) (#renameE env)
656 649
657 val classes = CM.map (fn class => 650 val classes = CM.map (fn class =>
658 {ground = KM.map (fn (ps, e) => (ps, liftExp e)) (#ground class), 651 {ground = map (fn (c, e) => (c, liftExp e)) (#ground class),
659 inclusions = #inclusions class}) (#classes env) 652 rules = #rules class}) (#classes env)
660 val classes = case class_pair_in t of 653 val classes = case class_head_in t of
661 NONE => classes 654 NONE => classes
662 | SOME (f, x) => 655 | SOME f =>
663 case CM.find (classes, f) of 656 case CM.find (classes, f) of
664 NONE => classes 657 NONE => classes
665 | SOME class => 658 | SOME class =>
666 let 659 let
667 val class = {ground = KM.insert (#ground class, (x, 0), ([], (ERel 0, #2 t))), 660 val class = {ground = (t, (ERel 0, #2 t)) :: #ground class,
668 inclusions = #inclusions class} 661 rules = #rules class}
669 in 662 in
670 CM.insert (classes, f, class) 663 CM.insert (classes, f, class)
671 end 664 end
672 in 665 in
673 {renameK = #renameK env, 666 {renameK = #renameK env,
694 end 687 end
695 688
696 fun lookupERel (env : env) n = 689 fun lookupERel (env : env) n =
697 (List.nth (#relE env, n)) 690 (List.nth (#relE env, n))
698 handle Subscript => raise UnboundRel n 691 handle Subscript => raise UnboundRel n
699
700 datatype rule =
701 Normal of int * (class_name * class_key) list * class_key
702 | Inclusion of class_name
703
704 fun containsOther k =
705 case k of
706 CkOther _ => true
707 | CkApp (k1, k2) => containsOther k1 orelse containsOther k2
708 | _ => false
709 692
710 fun rule_in c = 693 fun rule_in c =
711 let 694 let
712 fun quantifiers (c, nvars) = 695 fun quantifiers (c, nvars) =
713 case #1 c of 696 case #1 c of
715 | _ => 698 | _ =>
716 let 699 let
717 fun clauses (c, hyps) = 700 fun clauses (c, hyps) =
718 case #1 c of 701 case #1 c of
719 TFun (hyp, c) => 702 TFun (hyp, c) =>
720 (case class_pair_in hyp of 703 (case class_head_in hyp of
721 SOME (p as (_, CkRel _)) => clauses (c, p :: hyps) 704 SOME _ => clauses (c, hyp :: hyps)
722 | _ => NONE) 705 | NONE => NONE)
723 | _ => 706 | _ =>
724 case class_pair_in c of 707 case class_head_in c of
725 NONE => NONE 708 NONE => NONE
726 | SOME (cn, ck) => 709 | SOME f => SOME (f, nvars, rev hyps, c)
727 let
728 fun dearg (ck, i) =
729 if i >= nvars then
730 if containsOther ck
731 orelse List.exists (fn (_, k) => containsOther k) hyps then
732 NONE
733 else
734 SOME (cn, Normal (nvars, hyps, ck))
735 else case ck of
736 CkApp (ck, CkRel i') =>
737 if i' = i then
738 dearg (ck, i + 1)
739 else
740 NONE
741 | _ => NONE
742 in
743 dearg (ck, 0)
744 end
745 in 710 in
746 clauses (c, []) 711 clauses (c, [])
747 end 712 end
748 in 713 in
749 case #1 c of 714 quantifiers (c, 0)
750 TCFun (_, _, _, (TFun ((CApp (f1, (CRel 0, _)), _),
751 (CApp (f2, (CRel 0, _)), _)), _)) =>
752 (case (class_name_in f1, class_name_in f2) of
753 (SOME f1, SOME f2) => SOME (f2, Inclusion f1)
754 | _ => NONE)
755 | _ => quantifiers (c, 0)
756 end
757
758 fun inclusion (classes : class CM.map, init, inclusions, f, e : exp) =
759 let
760 fun search (f, fs) =
761 if f = init then
762 NONE
763 else if CS.member (fs, f) then
764 SOME fs
765 else
766 let
767 val fs = CS.add (fs, f)
768 in
769 case CM.find (classes, f) of
770 NONE => SOME fs
771 | SOME {inclusions = fs', ...} =>
772 CM.foldli (fn (f', _, fs) =>
773 case fs of
774 NONE => NONE
775 | SOME fs => search (f', fs)) (SOME fs) fs'
776 end
777 in
778 case search (f, CS.empty) of
779 SOME _ => CM.insert (inclusions, f, e)
780 | NONE => (ErrorMsg.errorAt (#2 e) "Type class inclusion would create a cycle";
781 inclusions)
782 end 715 end
783 716
784 fun pushENamedAs (env : env) x n t = 717 fun pushENamedAs (env : env) x n t =
785 let 718 let
786 val classes = #classes env 719 val classes = #classes env
787 val classes = case rule_in t of 720 val classes = case rule_in t of
788 NONE => classes 721 NONE => classes
789 | SOME (f, rule) => 722 | SOME (f, nvs, cs, c) =>
790 case CM.find (classes, f) of 723 case CM.find (classes, f) of
791 NONE => classes 724 NONE => classes
792 | SOME class => 725 | SOME class =>
793 let 726 let
794 val e = (ENamed n, #2 t) 727 val e = (ENamed n, #2 t)
795 728
796 val class = 729 val class =
797 case rule of 730 {ground = #ground class,
798 Normal (nvars, hyps, x) => 731 rules = (nvs, cs, c, e) :: #rules class}
799 {ground = KM.insert (#ground class, (x, nvars), (hyps, e)),
800 inclusions = #inclusions class}
801 | Inclusion f' =>
802 {ground = #ground class,
803 inclusions = inclusion (classes, f, #inclusions class, f', e)}
804 in 732 in
805 CM.insert (classes, f, class) 733 CM.insert (classes, f, class)
806 end 734 end
807 in 735 in
808 {renameK = #renameK env, 736 {renameK = #renameK env,
982 NONE => c 910 NONE => c
983 | SOME nx => CModProj (m1, ms', nx)) 911 | SOME nx => CModProj (m1, ms', nx))
984 | CApp (c1, c2) => CApp ((sgnS_con' arg (#1 c1), #2 c1), 912 | CApp (c1, c2) => CApp ((sgnS_con' arg (#1 c1), #2 c1),
985 (sgnS_con' arg (#1 c2), #2 c2)) 913 (sgnS_con' arg (#1 c2), #2 c2))
986 | _ => c 914 | _ => c
987
988 fun sgnS_class_name (arg as (m1, ms', (sgns, strs, cons))) nm =
989 case nm of
990 ClProj (m1, ms, x) =>
991 (case IM.find (strs, m1) of
992 NONE => nm
993 | SOME m1x => ClProj (m1, ms' @ m1x :: ms, x))
994 | ClNamed n =>
995 (case IM.find (cons, n) of
996 NONE => nm
997 | SOME nx => ClProj (m1, ms', nx))
998
999 fun sgnS_class_key (arg as (m1, ms', (sgns, strs, cons))) k =
1000 case k of
1001 CkProj (m1, ms, x) =>
1002 (case IM.find (strs, m1) of
1003 NONE => k
1004 | SOME m1x => CkProj (m1, ms' @ m1x :: ms, x))
1005 | CkNamed n =>
1006 (case IM.find (cons, n) of
1007 NONE => k
1008 | SOME nx => CkProj (m1, ms', nx))
1009 | CkApp (k1, k2) => CkApp (sgnS_class_key arg k1,
1010 sgnS_class_key arg k2)
1011 | _ => k
1012 915
1013 fun sgnS_sgn (str, (sgns, strs, cons)) sgn = 916 fun sgnS_sgn (str, (sgns, strs, cons)) sgn =
1014 case sgn of 917 case sgn of
1015 SgnProj (m1, ms, x) => 918 SgnProj (m1, ms, x) =>
1016 (case IM.find (strs, m1) of 919 (case IM.find (strs, m1) of
1118 | SgiClassAbs (x, n, _) => found (x, n) 1021 | SgiClassAbs (x, n, _) => found (x, n)
1119 | SgiClass (x, n, _, _) => found (x, n) 1022 | SgiClass (x, n, _, _) => found (x, n)
1120 | SgiVal (x, n, c) => 1023 | SgiVal (x, n, c) =>
1121 (case rule_in c of 1024 (case rule_in c of
1122 NONE => default () 1025 NONE => default ()
1123 | SOME (cn, rule) => 1026 | SOME (cn, nvs, cs, c) =>
1124 let 1027 let
1125 val globalizeN = sgnS_class_name (m1, ms, fmap) 1028 val loc = #2 c
1126 val globalize = sgnS_class_key (m1, ms, fmap) 1029 fun globalize (c, loc) = (sgnS_con' (m1, ms, fmap) c, loc)
1127
1128 fun unravel c =
1129 case c of
1130 ClNamed n =>
1131 ((case lookupCNamed env n of
1132 (_, _, SOME c') =>
1133 (case class_name_in c' of
1134 NONE => c
1135 | SOME k => unravel k)
1136 | _ => c)
1137 handle UnboundNamed _ => c)
1138 | _ => c
1139 1030
1140 val nc = 1031 val nc =
1141 case cn of 1032 case cn of
1142 ClNamed f => IM.find (newClasses, f) 1033 ClNamed f => IM.find (newClasses, f)
1143 | _ => NONE 1034 | _ => NONE
1148 val classes = 1039 val classes =
1149 case CM.find (classes, cn) of 1040 case CM.find (classes, cn) of
1150 NONE => classes 1041 NONE => classes
1151 | SOME class => 1042 | SOME class =>
1152 let 1043 let
1153 val e = (EModProj (m1, ms, x), 1044 val e = (EModProj (m1, ms, x), #2 sgn)
1154 #2 sgn)
1155 1045
1156 val class = 1046 val class =
1157 case rule of 1047 {ground = #ground class,
1158 Normal (nvars, hyps, a) => 1048 rules = (nvs,
1159 {ground = 1049 map globalize cs,
1160 KM.insert (#ground class, (globalize a, nvars), 1050 globalize c,
1161 (map (fn (n, k) => 1051 e) :: #rules class}
1162 (globalizeN n,
1163 globalize k)) hyps, e)),
1164 inclusions = #inclusions class}
1165 | Inclusion f' =>
1166 {ground = #ground class,
1167 inclusions = inclusion (classes, cn,
1168 #inclusions class,
1169 globalizeN f', e)}
1170 in 1052 in
1171 CM.insert (classes, cn, class) 1053 CM.insert (classes, cn, class)
1172 end 1054 end
1173 in 1055 in
1174 (classes, 1056 (classes,
1186 | SOME class => 1068 | SOME class =>
1187 let 1069 let
1188 val e = (EModProj (m1, ms, x), #2 sgn) 1070 val e = (EModProj (m1, ms, x), #2 sgn)
1189 1071
1190 val class = 1072 val class =
1191 case rule of 1073 {ground = #ground class,
1192 Normal (nvars, hyps, a) => 1074 rules = (nvs,
1193 {ground = 1075 map globalize cs,
1194 KM.insert (#ground class, (globalize a, nvars), 1076 globalize c,
1195 (map (fn (n, k) => 1077 e) :: #rules class}
1196 (globalizeN n,
1197 globalize k)) hyps, e)),
1198 inclusions = #inclusions class}
1199 | Inclusion f' =>
1200 {ground = #ground class,
1201 inclusions = inclusion (classes, cn,
1202 #inclusions class,
1203 globalizeN f', e)}
1204 in 1078 in
1205 CM.insert (classes, cn, class) 1079 CM.insert (classes, cn, class)
1206 end 1080 end
1207 in 1081 in
1208 (classes, 1082 (classes,
1299 | SgiVal (x, n, t) => pushENamedAs env x n t 1173 | SgiVal (x, n, t) => pushENamedAs env x n t
1300 | SgiStr (x, n, sgn) => pushStrNamedAs env x n sgn 1174 | SgiStr (x, n, sgn) => pushStrNamedAs env x n sgn
1301 | SgiSgn (x, n, sgn) => pushSgnNamedAs env x n sgn 1175 | SgiSgn (x, n, sgn) => pushSgnNamedAs env x n sgn
1302 | SgiConstraint _ => env 1176 | SgiConstraint _ => env
1303 1177
1304 | SgiClassAbs (x, n, k) => pushCNamedAs env x n (KArrow (k, (KType, loc)), loc) NONE 1178 | SgiClassAbs (x, n, k) => pushCNamedAs env x n k NONE
1305 | SgiClass (x, n, k, c) => pushCNamedAs env x n (KArrow (k, (KType, loc)), loc) (SOME c) 1179 | SgiClass (x, n, k, c) => pushCNamedAs env x n k (SOME c)
1306 1180
1307 fun sgnSubCon x = 1181 fun sgnSubCon x =
1308 ElabUtil.Con.map {kind = id, 1182 ElabUtil.Con.map {kind = id,
1309 con = sgnS_con x} 1183 con = sgnS_con x}
1310 1184