Mercurial > urweb
comparison src/elab_env.sml @ 753:d484df4e841a
Preparing to allow views in SELECT FROM clauses
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 28 Apr 2009 14:02:23 -0400 |
parents | 059074c8d2fc |
children | 8688e01ae469 |
comparison
equal
deleted
inserted
replaced
752:bc5cfd6cb30f | 753:d484df4e841a |
---|---|
587 | _ => c, | 587 | _ => c, |
588 bind = fn (d, U.Con.RelC _) => d + 1 | 588 bind = fn (d, U.Con.RelC _) => d + 1 |
589 | (d, _) => d} | 589 | (d, _) => d} |
590 0 | 590 0 |
591 | 591 |
592 fun postUnify x = | 592 exception Bad of con * con |
593 let | 593 |
594 fun unify (c1, c2) = | 594 fun resolveClass (hnorm : con -> con) (consEq : con * con -> bool) (env : env) = |
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) = | |
642 let | 595 let |
643 fun resolve c = | 596 fun resolve c = |
644 let | 597 let |
645 fun doHead f = | 598 fun doHead f = |
646 case CM.find (#classes env, f) of | 599 case CM.find (#classes env, f) of |
647 NONE => NONE | 600 NONE => NONE |
648 | SOME class => | 601 | SOME class => |
649 let | 602 let |
650 val loc = #2 c | 603 val loc = #2 c |
604 | |
605 fun generalize (c as (_, loc)) = | |
606 case #1 c of | |
607 CApp (f, x) => | |
608 let | |
609 val (f, equate) = generalize f | |
610 | |
611 fun isRecord () = | |
612 let | |
613 val rk = ref NONE | |
614 val k = (KUnif (loc, "k", rk), loc) | |
615 val r = ref NONE | |
616 val rc = (CUnif (loc, k, "x", r), loc) | |
617 in | |
618 ((CApp (f, rc), loc), | |
619 fn () => (if consEq (rc, x) then | |
620 true | |
621 else | |
622 (raise Bad (rc, x); | |
623 false)) | |
624 andalso equate ()) | |
625 end | |
626 in | |
627 case #1 x of | |
628 CConcat _ => isRecord () | |
629 | CRecord _ => isRecord () | |
630 | _ => ((CApp (f, x), loc), equate) | |
631 end | |
632 | _ => (c, fn () => true) | |
633 | |
634 val (c, equate) = generalize c | |
651 | 635 |
652 fun tryRules rules = | 636 fun tryRules rules = |
653 case rules of | 637 case rules of |
654 [] => NONE | 638 [] => NONE |
655 | (nRs, cs, c', e) :: rules' => | 639 | (nRs, cs, c', e) :: rules' => |
658 | SOME rs => | 642 | SOME rs => |
659 let | 643 let |
660 val eos = map (resolve o unifySubst rs) cs | 644 val eos = map (resolve o unifySubst rs) cs |
661 in | 645 in |
662 if List.exists (not o Option.isSome) eos | 646 if List.exists (not o Option.isSome) eos |
663 orelse not (postUnifies (c, unifySubst rs c')) then | 647 orelse not (equate ()) |
648 orelse not (consEq (c, unifySubst rs c')) then | |
664 tryRules rules' | 649 tryRules rules' |
665 else | 650 else |
666 let | 651 let |
667 val es = List.mapPartial (fn x => x) eos | 652 val es = List.mapPartial (fn x => x) eos |
668 | 653 |