comparison src/elab_env.sml @ 750:059074c8d2fc

LEFT JOIN
author Adam Chlipala <adamc@hcoop.net>
date Tue, 28 Apr 2009 11:05:28 -0400
parents 9864b64b1700
children d484df4e841a
comparison
equal deleted inserted replaced
749:16bfd9e244cd 750:059074c8d2fc
505 fun unify d (c1, c2) = 505 fun unify d (c1, c2) =
506 case (#1 c1, #1 c2) of 506 case (#1 c1, #1 c2) of
507 (CUnif (_, _, _, ref (SOME c1)), _) => unify d (c1, c2) 507 (CUnif (_, _, _, ref (SOME c1)), _) => unify d (c1, c2)
508 | (_, CUnif (_, _, _, ref (SOME c2))) => unify d (c1, c2) 508 | (_, CUnif (_, _, _, ref (SOME c2))) => unify d (c1, c2)
509 509
510 | (CUnif _, _) => ()
511
510 | (c1', CRel n2) => 512 | (c1', CRel n2) =>
511 if n2 < d then 513 if n2 < d then
512 case c1' of 514 case c1' of
513 CRel n1 => if n1 = n2 then () else raise Unify 515 CRel n1 => if n1 = n2 then () else raise Unify
514 | _ => raise Unify 516 | _ => raise Unify
585 | _ => c, 587 | _ => c,
586 bind = fn (d, U.Con.RelC _) => d + 1 588 bind = fn (d, U.Con.RelC _) => d + 1
587 | (d, _) => d} 589 | (d, _) => d}
588 0 590 0
589 591
590 fun resolveClass (env : env) = 592 fun postUnify x =
593 let
594 fun unify (c1, c2) =
595 case (#1 c1, #1 c2) of
596 (CUnif (_, _, _, ref (SOME c1)), _) => unify (c1, c2)
597 | (_, CUnif (_, _, _, ref (SOME c2))) => unify (c1, c2)
598
599 | (CUnif (_, _, _, r), _) => r := SOME c2
600
601 | (TFun (d1, r1), TFun (d2, r2)) => (unify (d1, d2); unify (r1, r2))
602 | (TCFun (_, _, k1, r1), TCFun (_, _, k2, r2)) => (unifyKinds (k1, k2); unify (r1, r2))
603 | (TRecord c1, TRecord c2) => unify (c1, c2)
604 | (TDisjoint (a1, b1, c1), TDisjoint (a2, b2, c2)) =>
605 (unify (a1, a2); unify (b1, b2); unify (c1, c2))
606
607 | (CRel n1, CRel n2) => if n1 = n2 then () else raise Unify
608 | (CNamed n1, CNamed n2) => if n1 = n2 then () else raise Unify
609 | (CModProj (n1, ms1, x1), CModProj (n2, ms2, x2)) =>
610 if n1 = n2 andalso ms1 = ms2 andalso x1 = x2 then () else raise Unify
611 | (CApp (f1, x1), CApp (f2, x2)) => (unify (f1, f2); unify (x1, x2))
612 | (CAbs (_, k1, b1), CAbs (_, k2, b2)) => (unifyKinds (k1, k2); unify (b1, b2))
613
614 | (CKAbs (_, b1), CKAbs (_, b2)) => unify (b1, b2)
615 | (CKApp (c1, k1), CKApp (c2, k2)) => (unify (c1, c2); unifyKinds (k1, k2))
616 | (TKFun (_, c1), TKFun (_, c2)) => unify (c1, c2)
617
618 | (CName s1, CName s2) => if s1 = s2 then () else raise Unify
619
620 | (CRecord (k1, xcs1), CRecord (k2, xcs2)) =>
621 (unifyKinds (k1, k2);
622 ListPair.appEq (fn ((x1, c1), (x2, c2)) => (unify (x1, x2); unify (c1, c2))) (xcs1, xcs2)
623 handle ListPair.UnequalLengths => raise Unify)
624 | (CConcat (f1, x1), CConcat (f2, x2)) => (unify (f1, f2); unify (x1, x2))
625 | (CMap (d1, r1), CMap (d2, r2)) => (unifyKinds (d1, d2); unifyKinds (r1, r2))
626
627 | (CUnit, CUnit) => ()
628
629 | (CTuple cs1, CTuple cs2) => (ListPair.appEq unify (cs1, cs2)
630 handle ListPair.UnequalLengths => raise Unify)
631 | (CProj (c1, n1), CProj (c2, n2)) => (unify (c1, c2);
632 if n1 = n2 then () else raise Unify)
633
634 | _ => raise Unify
635 in
636 unify x
637 end
638
639 fun postUnifies x = (postUnify x; true) handle Unify => false
640
641 fun resolveClass (hnorm : con -> con) (env : env) =
591 let 642 let
592 fun resolve c = 643 fun resolve c =
593 let 644 let
594 fun doHead f = 645 fun doHead f =
595 case CM.find (#classes env, f) of 646 case CM.find (#classes env, f) of
606 NONE => tryRules rules' 657 NONE => tryRules rules'
607 | SOME rs => 658 | SOME rs =>
608 let 659 let
609 val eos = map (resolve o unifySubst rs) cs 660 val eos = map (resolve o unifySubst rs) cs
610 in 661 in
611 if List.exists (not o Option.isSome) eos then 662 if List.exists (not o Option.isSome) eos
663 orelse not (postUnifies (c, unifySubst rs c')) then
612 tryRules rules' 664 tryRules rules'
613 else 665 else
614 let 666 let
615 val es = List.mapPartial (fn x => x) eos 667 val es = List.mapPartial (fn x => x) eos
616 668
632 | SOME _ => SOME e 684 | SOME _ => SOME e
633 in 685 in
634 tryGrounds (#ground class) 686 tryGrounds (#ground class)
635 end 687 end
636 in 688 in
637 case class_head_in c of 689 case #1 c of
638 SOME f => doHead f 690 TRecord c =>
639 | _ => NONE 691 (case #1 (hnorm c) of
692 CRecord (_, xts) =>
693 let
694 fun resolver (xts, acc) =
695 case xts of
696 [] => SOME (ERecord acc, #2 c)
697 | (x, t) :: xts =>
698 let
699 val t = hnorm t
700
701 val t = case t of
702 (CApp (f, x), loc) => (CApp (hnorm f, hnorm x), loc)
703 | _ => t
704 in
705 case resolve t of
706 NONE => NONE
707 | SOME e => resolver (xts, (x, e, t) :: acc)
708 end
709 in
710 resolver (xts, [])
711 end
712 | _ => NONE)
713 | _ =>
714 case class_head_in c of
715 SOME f => doHead f
716 | _ => NONE
640 end 717 end
641 in 718 in
642 resolve 719 resolve
643 end 720 end
644 721