Mercurial > urweb
comparison src/elaborate.sml @ 628:12b73f3c108e
Switch to TDisjoint from CDisjoint; still need to implement obligation generation at EDisjoint uses
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Tue, 24 Feb 2009 12:01:24 -0500 |
parents | 588b9d16b00a |
children | e68de2a5506b |
comparison
equal
deleted
inserted
replaced
627:f4f2b09a533a | 628:12b73f3c108e |
---|---|
206 case k of | 206 case k of |
207 L'.KUnif (_, _, ref (SOME k)) => hnormKind k | 207 L'.KUnif (_, _, ref (SOME k)) => hnormKind k |
208 | _ => kAll | 208 | _ => kAll |
209 | 209 |
210 open ElabOps | 210 open ElabOps |
211 val hnormCon = D.hnormCon | |
212 | 211 |
213 fun elabConHead (c as (_, loc)) k = | 212 fun elabConHead (c as (_, loc)) k = |
214 let | 213 let |
215 fun unravel (k, c) = | 214 fun unravel (k, c) = |
216 case hnormKind k of | 215 case hnormKind k of |
263 val (t', tk, gs) = elabCon (env', denv) t | 262 val (t', tk, gs) = elabCon (env', denv) t |
264 in | 263 in |
265 checkKind env t' tk ktype; | 264 checkKind env t' tk ktype; |
266 ((L'.TKFun (x, t'), loc), ktype, gs) | 265 ((L'.TKFun (x, t'), loc), ktype, gs) |
267 end | 266 end |
268 | L.CDisjoint (c1, c2, c) => | 267 | L.TDisjoint (c1, c2, c) => |
269 let | 268 let |
270 val (c1', k1, gs1) = elabCon (env, denv) c1 | 269 val (c1', k1, gs1) = elabCon (env, denv) c1 |
271 val (c2', k2, gs2) = elabCon (env, denv) c2 | 270 val (c2', k2, gs2) = elabCon (env, denv) c2 |
272 | 271 |
273 val ku1 = kunif loc | 272 val ku1 = kunif loc |
274 val ku2 = kunif loc | 273 val ku2 = kunif loc |
275 | 274 |
276 val (denv', gs3) = D.assert env denv (c1', c2') | 275 val denv' = D.assert env denv (c1', c2') |
277 val (c', k, gs4) = elabCon (env, denv') c | 276 val (c', k, gs4) = elabCon (env, denv') c |
278 in | 277 in |
279 checkKind env c1' k1 (L'.KRecord ku1, loc); | 278 checkKind env c1' k1 (L'.KRecord ku1, loc); |
280 checkKind env c2' k2 (L'.KRecord ku2, loc); | 279 checkKind env c2' k2 (L'.KRecord ku2, loc); |
281 | 280 |
282 ((L'.CDisjoint (L'.Instantiate, c1', c2', c'), loc), k, gs1 @ gs2 @ gs3 @ gs4) | 281 ((L'.TDisjoint (c1', c2', c'), loc), k, gs1 @ gs2 @ gs4) |
283 end | 282 end |
284 | L.TRecord c => | 283 | L.TRecord c => |
285 let | 284 let |
286 val (c', ck, gs) = elabCon (env, denv) c | 285 val (c', ck, gs) = elabCon (env, denv) c |
287 val k = (L'.KRecord ktype, loc) | 286 val k = (L'.KRecord ktype, loc) |
513 fun kindof env (c, loc) = | 512 fun kindof env (c, loc) = |
514 case c of | 513 case c of |
515 L'.TFun _ => ktype | 514 L'.TFun _ => ktype |
516 | L'.TCFun _ => ktype | 515 | L'.TCFun _ => ktype |
517 | L'.TRecord _ => ktype | 516 | L'.TRecord _ => ktype |
517 | L'.TDisjoint _ => ktype | |
518 | 518 |
519 | L'.CRel xn => #2 (E.lookupCRel env xn) | 519 | L'.CRel xn => #2 (E.lookupCRel env xn) |
520 | L'.CNamed xn => #2 (E.lookupCNamed env xn) | 520 | L'.CNamed xn => #2 (E.lookupCNamed env xn) |
521 | L'.CModProj (n, ms, x) => | 521 | L'.CModProj (n, ms, x) => |
522 let | 522 let |
536 (case hnormKind (kindof env c) of | 536 (case hnormKind (kindof env c) of |
537 (L'.KArrow (_, k), _) => k | 537 (L'.KArrow (_, k), _) => k |
538 | (L'.KError, _) => kerror | 538 | (L'.KError, _) => kerror |
539 | k => raise CUnify' (CKindof (k, c, "arrow"))) | 539 | k => raise CUnify' (CKindof (k, c, "arrow"))) |
540 | L'.CAbs (x, k, c) => (L'.KArrow (k, kindof (E.pushCRel env x k) c), loc) | 540 | L'.CAbs (x, k, c) => (L'.KArrow (k, kindof (E.pushCRel env x k) c), loc) |
541 | L'.CDisjoint (_, _, _, c) => kindof env c | 541 |
542 | 542 |
543 | L'.CName _ => kname | 543 | L'.CName _ => kname |
544 | 544 |
545 | L'.CRecord (k, _) => (L'.KRecord k, loc) | 545 | L'.CRecord (k, _) => (L'.KRecord k, loc) |
546 | L'.CConcat (c, _) => kindof env c | 546 | L'.CConcat (c, _) => kindof env c |
562 (case hnormKind (kindof env c) of | 562 (case hnormKind (kindof env c) of |
563 (L'.KFun (_, k'), _) => subKindInKind (0, k) k' | 563 (L'.KFun (_, k'), _) => subKindInKind (0, k) k' |
564 | k => raise CUnify' (CKindof (k, c, "kapp"))) | 564 | k => raise CUnify' (CKindof (k, c, "kapp"))) |
565 | L'.TKFun _ => ktype | 565 | L'.TKFun _ => ktype |
566 | 566 |
567 fun deConstraintCon (env, denv) c = | |
568 let | |
569 val (c, gs) = hnormCon (env, denv) c | |
570 in | |
571 case #1 c of | |
572 L'.CDisjoint (_, _, _, c) => | |
573 let | |
574 val (c', gs') = deConstraintCon (env, denv) c | |
575 in | |
576 (c', gs @ gs') | |
577 end | |
578 | _ => (c, gs) | |
579 end | |
580 | |
581 exception GuessFailure | 567 exception GuessFailure |
582 | 568 |
583 fun isUnitCon env (c, loc) = | 569 fun isUnitCon env (c, loc) = |
584 case c of | 570 case c of |
585 L'.TFun _ => false | 571 L'.TFun _ => false |
586 | L'.TCFun _ => false | 572 | L'.TCFun _ => false |
587 | L'.TRecord _ => false | 573 | L'.TRecord _ => false |
574 | L'.TDisjoint _ => false | |
588 | 575 |
589 | L'.CRel xn => #1 (#2 (E.lookupCRel env xn)) = L'.KUnit | 576 | L'.CRel xn => #1 (#2 (E.lookupCRel env xn)) = L'.KUnit |
590 | L'.CNamed xn => #1 (#2 (E.lookupCNamed env xn)) = L'.KUnit | 577 | L'.CNamed xn => #1 (#2 (E.lookupCNamed env xn)) = L'.KUnit |
591 | L'.CModProj (n, ms, x) => false | 578 | L'.CModProj (n, ms, x) => false |
592 (*let | 579 (*let |
606 (*(case hnormKind (kindof env c) of | 593 (*(case hnormKind (kindof env c) of |
607 (L'.KArrow (_, k), _) => #1 k = L'.KUnit | 594 (L'.KArrow (_, k), _) => #1 k = L'.KUnit |
608 | (L'.KError, _) => false | 595 | (L'.KError, _) => false |
609 | k => raise CUnify' (CKindof (k, c, "arrow")))*) | 596 | k => raise CUnify' (CKindof (k, c, "arrow")))*) |
610 | L'.CAbs _ => false | 597 | L'.CAbs _ => false |
611 | L'.CDisjoint (_, _, _, c) => false(*isUnitCon env c*) | |
612 | 598 |
613 | L'.CName _ => false | 599 | L'.CName _ => false |
614 | 600 |
615 | L'.CRecord _ => false | 601 | L'.CRecord _ => false |
616 | L'.CConcat _ => false | 602 | L'.CConcat _ => false |
629 | 615 |
630 | L'.CKAbs _ => false | 616 | L'.CKAbs _ => false |
631 | L'.CKApp _ => false | 617 | L'.CKApp _ => false |
632 | L'.TKFun _ => false | 618 | L'.TKFun _ => false |
633 | 619 |
634 fun unifyRecordCons (env, denv) (c1, c2) = | 620 fun unifyRecordCons env (c1, c2) = |
635 let | 621 let |
636 fun rkindof c = | 622 fun rkindof c = |
637 case hnormKind (kindof env c) of | 623 case hnormKind (kindof env c) of |
638 (L'.KRecord k, _) => k | 624 (L'.KRecord k, _) => k |
639 | (L'.KError, _) => kerror | 625 | (L'.KError, _) => kerror |
640 | k => raise CUnify' (CKindof (k, c, "record")) | 626 | k => raise CUnify' (CKindof (k, c, "record")) |
641 | 627 |
642 val k1 = rkindof c1 | 628 val k1 = rkindof c1 |
643 val k2 = rkindof c2 | 629 val k2 = rkindof c2 |
644 | 630 |
645 val (r1, gs1) = recordSummary (env, denv) c1 | 631 val r1 = recordSummary env c1 |
646 val (r2, gs2) = recordSummary (env, denv) c2 | 632 val r2 = recordSummary env c2 |
647 in | 633 in |
648 unifyKinds env k1 k2; | 634 unifyKinds env k1 k2; |
649 unifySummaries (env, denv) (k1, r1, r2); | 635 unifySummaries env (k1, r1, r2) |
650 gs1 @ gs2 | |
651 end | 636 end |
652 | 637 |
653 and recordSummary (env, denv) c = | 638 and recordSummary env c = |
654 let | 639 let |
655 val (c, gs) = hnormCon (env, denv) c | 640 val c = hnormCon env c |
656 | 641 |
657 val (sum, gs') = | 642 val sum = |
658 case c of | 643 case c of |
659 (L'.CRecord (_, xcs), _) => ({fields = xcs, unifs = [], others = []}, []) | 644 (L'.CRecord (_, xcs), _) => {fields = xcs, unifs = [], others = []} |
660 | (L'.CConcat (c1, c2), _) => | 645 | (L'.CConcat (c1, c2), _) => |
661 let | 646 let |
662 val (s1, gs1) = recordSummary (env, denv) c1 | 647 val s1 = recordSummary env c1 |
663 val (s2, gs2) = recordSummary (env, denv) c2 | 648 val s2 = recordSummary env c2 |
664 in | 649 in |
665 ({fields = #fields s1 @ #fields s2, | 650 {fields = #fields s1 @ #fields s2, |
666 unifs = #unifs s1 @ #unifs s2, | 651 unifs = #unifs s1 @ #unifs s2, |
667 others = #others s1 @ #others s2}, | 652 others = #others s1 @ #others s2} |
668 gs1 @ gs2) | |
669 end | 653 end |
670 | (L'.CUnif (_, _, _, ref (SOME c)), _) => recordSummary (env, denv) c | 654 | (L'.CUnif (_, _, _, ref (SOME c)), _) => recordSummary env c |
671 | c' as (L'.CUnif (_, _, _, r), _) => ({fields = [], unifs = [(c', r)], others = []}, []) | 655 | c' as (L'.CUnif (_, _, _, r), _) => {fields = [], unifs = [(c', r)], others = []} |
672 | c' => ({fields = [], unifs = [], others = [c']}, []) | 656 | c' => {fields = [], unifs = [], others = [c']} |
673 in | 657 in |
674 (sum, gs @ gs') | 658 sum |
675 end | 659 end |
676 | 660 |
677 and consEq (env, denv) (c1, c2) = | 661 and consEq env (c1, c2) = |
678 let | 662 (unifyCons env c1 c2; |
679 val gs = unifyCons (env, denv) c1 c2 | 663 true) |
680 in | |
681 List.all (fn (loc, env, denv, c1, c2) => | |
682 case D.prove env denv (c1, c2, loc) of | |
683 [] => true | |
684 | _ => false) gs | |
685 end | |
686 handle CUnify _ => false | 664 handle CUnify _ => false |
687 | 665 |
688 and consNeq env (c1, c2) = | 666 and consNeq env (c1, c2) = |
689 case (#1 (ElabOps.hnormCon env c1), #1 (ElabOps.hnormCon env c2)) of | 667 case (#1 (hnormCon env c1), #1 (hnormCon env c2)) of |
690 (L'.CName x1, L'.CName x2) => x1 <> x2 | 668 (L'.CName x1, L'.CName x2) => x1 <> x2 |
691 | _ => false | 669 | _ => false |
692 | 670 |
693 and unifySummaries (env, denv) (k, s1 : record_summary, s2 : record_summary) = | 671 and unifySummaries env (k, s1 : record_summary, s2 : record_summary) = |
694 let | 672 let |
695 val loc = #2 k | 673 val loc = #2 k |
696 (*val () = eprefaces "Summaries" [("#1", p_summary env s1), | 674 (*val () = eprefaces "Summaries" [("#1", p_summary env s1), |
697 ("#2", p_summary env s2)]*) | 675 ("#2", p_summary env s2)]*) |
698 | 676 |
718 em (ls1, ls2, []) | 696 em (ls1, ls2, []) |
719 end | 697 end |
720 | 698 |
721 val (fs1, fs2) = eatMatching (fn ((x1, c1), (x2, c2)) => | 699 val (fs1, fs2) = eatMatching (fn ((x1, c1), (x2, c2)) => |
722 not (consNeq env (x1, x2)) | 700 not (consNeq env (x1, x2)) |
723 andalso consEq (env, denv) (c1, c2) | 701 andalso consEq env (c1, c2) |
724 andalso consEq (env, denv) (x1, x2)) | 702 andalso consEq env (x1, x2)) |
725 (#fields s1, #fields s2) | 703 (#fields s1, #fields s2) |
726 (*val () = eprefaces "Summaries2" [("#1", p_summary env {fields = fs1, unifs = #unifs s1, others = #others s1}), | 704 (*val () = eprefaces "Summaries2" [("#1", p_summary env {fields = fs1, unifs = #unifs s1, others = #others s1}), |
727 ("#2", p_summary env {fields = fs2, unifs = #unifs s2, others = #others s2})]*) | 705 ("#2", p_summary env {fields = fs2, unifs = #unifs s2, others = #others s2})]*) |
728 val (unifs1, unifs2) = eatMatching (fn ((_, r1), (_, r2)) => r1 = r2) (#unifs s1, #unifs s2) | 706 val (unifs1, unifs2) = eatMatching (fn ((_, r1), (_, r2)) => r1 = r2) (#unifs s1, #unifs s2) |
729 val (others1, others2) = eatMatching (consEq (env, denv)) (#others s1, #others s2) | 707 val (others1, others2) = eatMatching (consEq env) (#others s1, #others s2) |
730 (*val () = eprefaces "Summaries3" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}), | 708 (*val () = eprefaces "Summaries3" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}), |
731 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*) | 709 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*) |
732 | 710 |
733 fun unifFields (fs, others, unifs) = | 711 fun unifFields (fs, others, unifs) = |
734 case (fs, others, unifs) of | 712 case (fs, others, unifs) of |
761 | 739 |
762 (*val () = eprefaces "Summaries4" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}), | 740 (*val () = eprefaces "Summaries4" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}), |
763 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*) | 741 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*) |
764 | 742 |
765 fun isGuessable (other, fs) = | 743 fun isGuessable (other, fs) = |
766 let | 744 (guessMap env (other, (L'.CRecord (k, fs), loc), GuessFailure); |
767 val gs = guessMap (env, denv) (other, (L'.CRecord (k, fs), loc), [], GuessFailure) | 745 true) |
768 in | |
769 List.all (fn (loc, env, denv, c1, c2) => | |
770 case D.prove env denv (c1, c2, loc) of | |
771 [] => true | |
772 | _ => false) gs | |
773 end | |
774 handle GuessFailure => false | 746 handle GuessFailure => false |
775 | 747 |
776 val (fs1, fs2, others1, others2) = | 748 val (fs1, fs2, others1, others2) = |
777 case (fs1, fs2, others1, others2) of | 749 case (fs1, fs2, others1, others2) of |
778 ([], _, [other1], []) => | 750 ([], _, [other1], []) => |
825 pairOffUnifs (unifs1, unifs2) | 797 pairOffUnifs (unifs1, unifs2) |
826 (*before eprefaces "Summaries'" [("#1", p_summary env s1), | 798 (*before eprefaces "Summaries'" [("#1", p_summary env s1), |
827 ("#2", p_summary env s2)]*) | 799 ("#2", p_summary env s2)]*) |
828 end | 800 end |
829 | 801 |
830 and guessMap (env, denv) (c1, c2, gs, ex) = | 802 and guessMap env (c1, c2, ex) = |
831 let | 803 let |
832 val loc = #2 c1 | 804 val loc = #2 c1 |
833 | 805 |
834 fun unfold (dom, ran, f, r, c) = | 806 fun unfold (dom, ran, f, r, c) = |
835 let | 807 let |
836 fun unfold (r, c) = | 808 fun unfold (r, c) = |
837 let | 809 case #1 c of |
838 val (c', gs1) = deConstraintCon (env, denv) c | 810 L'.CRecord (_, []) => unifyCons env r (L'.CRecord (dom, []), loc) |
839 in | 811 | L'.CRecord (_, [(x, v)]) => |
840 case #1 c' of | 812 let |
841 L'.CRecord (_, []) => | 813 val v' = case dom of |
842 let | 814 (L'.KUnit, _) => (L'.CUnit, loc) |
843 val gs2 = unifyCons (env, denv) r (L'.CRecord (dom, []), loc) | 815 | _ => cunif (loc, dom) |
844 in | 816 in |
845 gs1 @ gs2 | 817 unifyCons env v (L'.CApp (f, v'), loc); |
846 end | 818 unifyCons env r (L'.CRecord (dom, [(x, v')]), loc) |
847 | L'.CRecord (_, [(x, v)]) => | 819 end |
848 let | 820 | L'.CRecord (_, (x, v) :: rest) => |
849 val v' = case dom of | 821 let |
850 (L'.KUnit, _) => (L'.CUnit, loc) | 822 val r1 = cunif (loc, (L'.KRecord dom, loc)) |
851 | _ => cunif (loc, dom) | 823 val r2 = cunif (loc, (L'.KRecord dom, loc)) |
852 val gs2 = unifyCons (env, denv) v (L'.CApp (f, v'), loc) | 824 in |
853 | 825 unfold (r1, (L'.CRecord (ran, [(x, v)]), loc)); |
854 val gs3 = unifyCons (env, denv) r (L'.CRecord (dom, [(x, v')]), loc) | 826 unfold (r2, (L'.CRecord (ran, rest), loc)); |
855 in | 827 unifyCons env r (L'.CConcat (r1, r2), loc) |
856 gs1 @ gs2 @ gs3 | 828 end |
857 end | 829 | L'.CConcat (c1', c2') => |
858 | L'.CRecord (_, (x, v) :: rest) => | 830 let |
859 let | 831 val r1 = cunif (loc, (L'.KRecord dom, loc)) |
860 val r1 = cunif (loc, (L'.KRecord dom, loc)) | 832 val r2 = cunif (loc, (L'.KRecord dom, loc)) |
861 val r2 = cunif (loc, (L'.KRecord dom, loc)) | 833 in |
862 | 834 unfold (r1, c1'); |
863 val gs2 = unfold (r1, (L'.CRecord (ran, [(x, v)]), loc)) | 835 unfold (r2, c2'); |
864 val gs3 = unfold (r2, (L'.CRecord (ran, rest), loc)) | 836 unifyCons env r (L'.CConcat (r1, r2), loc) |
865 val gs4 = unifyCons (env, denv) r (L'.CConcat (r1, r2), loc) | 837 end |
866 in | 838 | _ => raise ex |
867 gs1 @ gs2 @ gs3 @ gs4 | |
868 end | |
869 | L'.CConcat (c1', c2') => | |
870 let | |
871 val r1 = cunif (loc, (L'.KRecord dom, loc)) | |
872 val r2 = cunif (loc, (L'.KRecord dom, loc)) | |
873 | |
874 val gs2 = unfold (r1, c1') | |
875 val gs3 = unfold (r2, c2') | |
876 val gs4 = unifyCons (env, denv) r (L'.CConcat (r1, r2), loc) | |
877 in | |
878 gs1 @ gs2 @ gs3 @ gs4 | |
879 end | |
880 | _ => raise ex | |
881 end | |
882 in | 839 in |
883 unfold (r, c) | 840 unfold (r, c) |
884 end | 841 end |
885 handle _ => (TextIO.print "Guess failure!\n"; raise ex) | 842 handle _ => (TextIO.print "Guess failure!\n"; raise ex) |
886 in | 843 in |
890 | (_, L'.CApp ((L'.CApp ((L'.CMap (dom, ran), _), f), _), r)) => | 847 | (_, L'.CApp ((L'.CApp ((L'.CMap (dom, ran), _), f), _), r)) => |
891 unfold (dom, ran, f, r, c1) | 848 unfold (dom, ran, f, r, c1) |
892 | _ => raise ex | 849 | _ => raise ex |
893 end | 850 end |
894 | 851 |
895 and unifyCons' (env, denv) c1 c2 = | 852 and unifyCons' env c1 c2 = |
896 case (#1 c1, #1 c2) of | 853 if isUnitCon env c1 andalso isUnitCon env c2 then |
897 (L'.CDisjoint (_, x1, y1, t1), L'.CDisjoint (_, x2, y2, t2)) => | 854 () |
855 else | |
898 let | 856 let |
899 val gs1 = unifyCons' (env, denv) x1 x2 | 857 (*val befor = Time.now () |
900 val gs2 = unifyCons' (env, denv) y1 y2 | 858 val old1 = c1 |
901 val (denv', gs3) = D.assert env denv (x1, y1) | 859 val old2 = c2*) |
902 val gs4 = unifyCons' (env, denv') t1 t2 | 860 val c1 = hnormCon env c1 |
861 val c2 = hnormCon env c2 | |
903 in | 862 in |
904 gs1 @ gs2 @ gs3 @ gs4 | 863 unifyCons'' env c1 c2 |
864 handle ex => guessMap env (c1, c2, ex) | |
905 end | 865 end |
906 | _ => | 866 |
907 if isUnitCon env c1 andalso isUnitCon env c2 then | 867 and unifyCons'' env (c1All as (c1, loc)) (c2All as (c2, _)) = |
908 [] | |
909 else | |
910 let | |
911 (*val befor = Time.now () | |
912 val old1 = c1 | |
913 val old2 = c2*) | |
914 val (c1, gs1) = hnormCon (env, denv) c1 | |
915 val (c2, gs2) = hnormCon (env, denv) c2 | |
916 in | |
917 let | |
918 (*val () = prefaces "unifyCons'" [("old1", p_con env old1), | |
919 ("old2", p_con env old2), | |
920 ("c1", p_con env c1), | |
921 ("c2", p_con env c2)]*) | |
922 | |
923 val gs3 = unifyCons'' (env, denv) c1 c2 | |
924 in | |
925 gs1 @ gs2 @ gs3 | |
926 end | |
927 handle ex => guessMap (env, denv) (c1, c2, gs1 @ gs2, ex) | |
928 end | |
929 | |
930 and unifyCons'' (env, denv) (c1All as (c1, loc)) (c2All as (c2, _)) = | |
931 let | 868 let |
932 fun err f = raise CUnify' (f (c1All, c2All)) | 869 fun err f = raise CUnify' (f (c1All, c2All)) |
933 | 870 |
934 fun isRecord () = unifyRecordCons (env, denv) (c1All, c2All) | 871 fun isRecord () = unifyRecordCons env (c1All, c2All) |
935 in | 872 in |
936 (*eprefaces "unifyCons''" [("c1All", p_con env c1All), | 873 (*eprefaces "unifyCons''" [("c1All", p_con env c1All), |
937 ("c2All", p_con env c2All)];*) | 874 ("c2All", p_con env c2All)];*) |
938 | 875 |
939 case (c1, c2) of | 876 case (c1, c2) of |
940 (L'.CUnit, L'.CUnit) => [] | 877 (L'.CUnit, L'.CUnit) => () |
941 | 878 |
942 | (L'.TFun (d1, r1), L'.TFun (d2, r2)) => | 879 | (L'.TFun (d1, r1), L'.TFun (d2, r2)) => |
943 unifyCons' (env, denv) d1 d2 | 880 (unifyCons' env d1 d2; |
944 @ unifyCons' (env, denv) r1 r2 | 881 unifyCons' env r1 r2) |
945 | (L'.TCFun (expl1, x1, d1, r1), L'.TCFun (expl2, _, d2, r2)) => | 882 | (L'.TCFun (expl1, x1, d1, r1), L'.TCFun (expl2, _, d2, r2)) => |
946 if expl1 <> expl2 then | 883 if expl1 <> expl2 then |
947 err CExplicitness | 884 err CExplicitness |
948 else | 885 else |
949 (unifyKinds env d1 d2; | 886 (unifyKinds env d1 d2; |
950 let | 887 let |
951 val denv' = D.enter denv | |
952 (*val befor = Time.now ()*) | 888 (*val befor = Time.now ()*) |
953 val env' = E.pushCRel env x1 d1 | 889 val env' = E.pushCRel env x1 d1 |
954 in | 890 in |
955 (*TextIO.print ("E.pushCRel: " | 891 (*TextIO.print ("E.pushCRel: " |
956 ^ LargeReal.toString (Time.toReal (Time.- (Time.now (), befor))) | 892 ^ LargeReal.toString (Time.toReal (Time.- (Time.now (), befor))) |
957 ^ "\n");*) | 893 ^ "\n");*) |
958 unifyCons' (env', denv') r1 r2 | 894 unifyCons' env' r1 r2 |
959 end) | 895 end) |
960 | (L'.TRecord r1, L'.TRecord r2) => unifyCons' (env, denv) r1 r2 | 896 | (L'.TRecord r1, L'.TRecord r2) => unifyCons' env r1 r2 |
897 | (L'.TDisjoint (c1, d1, e1), L'.TDisjoint (c2, d2, e2)) => | |
898 (unifyCons' env c1 c2; | |
899 unifyCons' env d1 d2; | |
900 unifyCons' env e1 e2) | |
961 | 901 |
962 | (L'.CRel n1, L'.CRel n2) => | 902 | (L'.CRel n1, L'.CRel n2) => |
963 if n1 = n2 then | 903 if n1 = n2 then |
964 [] | 904 () |
965 else | 905 else |
966 err CIncompatible | 906 err CIncompatible |
967 | (L'.CNamed n1, L'.CNamed n2) => | 907 | (L'.CNamed n1, L'.CNamed n2) => |
968 if n1 = n2 then | 908 if n1 = n2 then |
969 [] | 909 () |
970 else | 910 else |
971 err CIncompatible | 911 err CIncompatible |
972 | 912 |
973 | (L'.CApp (d1, r1), L'.CApp (d2, r2)) => | 913 | (L'.CApp (d1, r1), L'.CApp (d2, r2)) => |
974 (unifyCons' (env, denv) d1 d2; | 914 (unifyCons' env d1 d2; |
975 unifyCons' (env, denv) r1 r2) | 915 unifyCons' env r1 r2) |
976 | (L'.CAbs (x1, k1, c1), L'.CAbs (_, k2, c2)) => | 916 | (L'.CAbs (x1, k1, c1), L'.CAbs (_, k2, c2)) => |
977 (unifyKinds env k1 k2; | 917 (unifyKinds env k1 k2; |
978 unifyCons' (E.pushCRel env x1 k1, D.enter denv) c1 c2) | 918 unifyCons' (E.pushCRel env x1 k1) c1 c2) |
979 | 919 |
980 | (L'.CName n1, L'.CName n2) => | 920 | (L'.CName n1, L'.CName n2) => |
981 if n1 = n2 then | 921 if n1 = n2 then |
982 [] | 922 () |
983 else | 923 else |
984 err CIncompatible | 924 err CIncompatible |
985 | 925 |
986 | (L'.CModProj (n1, ms1, x1), L'.CModProj (n2, ms2, x2)) => | 926 | (L'.CModProj (n1, ms1, x1), L'.CModProj (n2, ms2, x2)) => |
987 if n1 = n2 andalso ms1 = ms2 andalso x1 = x2 then | 927 if n1 = n2 andalso ms1 = ms2 andalso x1 = x2 then |
988 [] | 928 () |
989 else | 929 else |
990 err CIncompatible | 930 err CIncompatible |
991 | 931 |
992 | (L'.CTuple cs1, L'.CTuple cs2) => | 932 | (L'.CTuple cs1, L'.CTuple cs2) => |
993 ((ListPair.foldlEq (fn (c1, c2, gs) => | 933 ((ListPair.appEq (fn (c1, c2) => unifyCons' env c1 c2) (cs1, cs2)) |
994 let | |
995 val gs' = unifyCons' (env, denv) c1 c2 | |
996 in | |
997 gs' @ gs | |
998 end) [] (cs1, cs2)) | |
999 handle ListPair.UnequalLengths => err CIncompatible) | 934 handle ListPair.UnequalLengths => err CIncompatible) |
1000 | 935 |
1001 | (L'.CProj ((L'.CUnif (_, _, _, ref (SOME c1)), loc), n1), _) => | 936 | (L'.CProj ((L'.CUnif (_, _, _, ref (SOME c1)), loc), n1), _) => |
1002 unifyCons' (env, denv) (L'.CProj (c1, n1), loc) c2All | 937 unifyCons' env (L'.CProj (c1, n1), loc) c2All |
1003 | (_, L'.CProj ((L'.CUnif (_, _, _, ref (SOME c2)), loc), n2)) => | 938 | (_, L'.CProj ((L'.CUnif (_, _, _, ref (SOME c2)), loc), n2)) => |
1004 unifyCons' (env, denv) c1All (L'.CProj (c2, n2), loc) | 939 unifyCons' env c1All (L'.CProj (c2, n2), loc) |
1005 | (L'.CProj ((L'.CUnif (_, (L'.KTuple ks, _), _, r), loc), n), _) => | 940 | (L'.CProj ((L'.CUnif (_, (L'.KTuple ks, _), _, r), loc), n), _) => |
1006 let | 941 let |
1007 val us = map (fn k => cunif (loc, k)) ks | 942 val us = map (fn k => cunif (loc, k)) ks |
1008 in | 943 in |
1009 r := SOME (L'.CTuple us, loc); | 944 r := SOME (L'.CTuple us, loc); |
1010 unifyCons' (env, denv) (List.nth (us, n - 1)) c2All | 945 unifyCons' env (List.nth (us, n - 1)) c2All |
1011 end | 946 end |
1012 | (_, L'.CProj ((L'.CUnif (_, (L'.KTuple ks, _), _, r), loc), n)) => | 947 | (_, L'.CProj ((L'.CUnif (_, (L'.KTuple ks, _), _, r), loc), n)) => |
1013 let | 948 let |
1014 val us = map (fn k => cunif (loc, k)) ks | 949 val us = map (fn k => cunif (loc, k)) ks |
1015 in | 950 in |
1016 r := SOME (L'.CTuple us, loc); | 951 r := SOME (L'.CTuple us, loc); |
1017 unifyCons' (env, denv) c1All (List.nth (us, n - 1)) | 952 unifyCons' env c1All (List.nth (us, n - 1)) |
1018 end | 953 end |
1019 | (L'.CProj (c1, n1), L'.CProj (c2, n2)) => | 954 | (L'.CProj (c1, n1), L'.CProj (c2, n2)) => |
1020 if n1 = n2 then | 955 if n1 = n2 then |
1021 unifyCons' (env, denv) c1 c2 | 956 unifyCons' env c1 c2 |
1022 else | 957 else |
1023 err CIncompatible | 958 err CIncompatible |
1024 | 959 |
1025 | (L'.CMap (dom1, ran1), L'.CMap (dom2, ran2)) => | 960 | (L'.CMap (dom1, ran1), L'.CMap (dom2, ran2)) => |
1026 (unifyKinds env dom1 dom2; | 961 (unifyKinds env dom1 dom2; |
1027 unifyKinds env ran1 ran2; | 962 unifyKinds env ran1 ran2) |
1028 []) | |
1029 | 963 |
1030 | (L'.CKAbs (x, c1), L'.CKAbs (_, c2)) => | 964 | (L'.CKAbs (x, c1), L'.CKAbs (_, c2)) => |
1031 unifyCons' (E.pushKRel env x, denv) c1 c2 | 965 unifyCons' (E.pushKRel env x) c1 c2 |
1032 | (L'.CKApp (c1, k1), L'.CKApp (c2, k2)) => | 966 | (L'.CKApp (c1, k1), L'.CKApp (c2, k2)) => |
1033 (unifyKinds env k1 k2; | 967 (unifyKinds env k1 k2; |
1034 unifyCons' (env, denv) c1 c2) | 968 unifyCons' env c1 c2) |
1035 | (L'.TKFun (x, c1), L'.TKFun (_, c2)) => | 969 | (L'.TKFun (x, c1), L'.TKFun (_, c2)) => |
1036 unifyCons' (E.pushKRel env x, denv) c1 c2 | 970 unifyCons' (E.pushKRel env x) c1 c2 |
1037 | 971 |
1038 | (L'.CError, _) => [] | 972 | (L'.CError, _) => () |
1039 | (_, L'.CError) => [] | 973 | (_, L'.CError) => () |
1040 | 974 |
1041 | (L'.CRecord _, _) => isRecord () | 975 | (L'.CRecord _, _) => isRecord () |
1042 | (_, L'.CRecord _) => isRecord () | 976 | (_, L'.CRecord _) => isRecord () |
1043 | (L'.CConcat _, _) => isRecord () | 977 | (L'.CConcat _, _) => isRecord () |
1044 | (_, L'.CConcat _) => isRecord () | 978 | (_, L'.CConcat _) => isRecord () |
1045 | 979 |
1046 | (L'.CUnif (_, k1, _, r1), L'.CUnif (_, k2, _, r2)) => | 980 | (L'.CUnif (_, k1, _, r1), L'.CUnif (_, k2, _, r2)) => |
1047 if r1 = r2 then | 981 if r1 = r2 then |
1048 [] | 982 () |
1049 else | 983 else |
1050 (unifyKinds env k1 k2; | 984 (unifyKinds env k1 k2; |
1051 r1 := SOME c2All; | 985 r1 := SOME c2All) |
1052 []) | |
1053 | 986 |
1054 | (L'.CUnif (_, _, _, r), _) => | 987 | (L'.CUnif (_, _, _, r), _) => |
1055 if occursCon r c2All then | 988 if occursCon r c2All then |
1056 err COccursCheckFailed | 989 err COccursCheckFailed |
1057 else | 990 else |
1058 (r := SOME c2All; | 991 r := SOME c2All |
1059 []) | |
1060 | (_, L'.CUnif (_, _, _, r)) => | 992 | (_, L'.CUnif (_, _, _, r)) => |
1061 if occursCon r c1All then | 993 if occursCon r c1All then |
1062 err COccursCheckFailed | 994 err COccursCheckFailed |
1063 else | 995 else |
1064 (r := SOME c1All; | 996 r := SOME c1All |
1065 []) | |
1066 | 997 |
1067 | _ => err CIncompatible | 998 | _ => err CIncompatible |
1068 end | 999 end |
1069 | 1000 |
1070 and unifyCons (env, denv) c1 c2 = | 1001 and unifyCons env c1 c2 = |
1071 unifyCons' (env, denv) c1 c2 | 1002 unifyCons' env c1 c2 |
1072 handle CUnify' err => raise CUnify (c1, c2, err) | 1003 handle CUnify' err => raise CUnify (c1, c2, err) |
1073 | KUnify args => raise CUnify (c1, c2, CKind args) | 1004 | KUnify args => raise CUnify (c1, c2, CKind args) |
1074 | 1005 |
1075 fun checkCon (env, denv) e c1 c2 = | 1006 fun checkCon env e c1 c2 = |
1076 unifyCons (env, denv) c1 c2 | 1007 unifyCons env c1 c2 |
1077 handle CUnify (c1, c2, err) => | 1008 handle CUnify (c1, c2, err) => |
1078 (expError env (Unify (e, c1, c2, err)); | 1009 expError env (Unify (e, c1, c2, err)) |
1079 []) | 1010 |
1080 | 1011 fun checkPatCon env p c1 c2 = |
1081 fun checkPatCon (env, denv) p c1 c2 = | 1012 unifyCons env c1 c2 |
1082 unifyCons (env, denv) c1 c2 | |
1083 handle CUnify (c1, c2, err) => | 1013 handle CUnify (c1, c2, err) => |
1084 (expError env (PatUnify (p, c1, c2, err)); | 1014 expError env (PatUnify (p, c1, c2, err)) |
1085 []) | |
1086 | 1015 |
1087 fun primType env p = | 1016 fun primType env p = |
1088 case p of | 1017 case p of |
1089 P.Int _ => !int | 1018 P.Int _ => !int |
1090 | P.Float _ => !float | 1019 | P.Float _ => !float |
1094 Disjoint of D.goal | 1023 Disjoint of D.goal |
1095 | TypeClass of E.env * L'.con * L'.exp option ref * ErrorMsg.span | 1024 | TypeClass of E.env * L'.con * L'.exp option ref * ErrorMsg.span |
1096 | 1025 |
1097 val enD = map Disjoint | 1026 val enD = map Disjoint |
1098 | 1027 |
1099 fun elabHead (env, denv) infer (e as (_, loc)) t = | 1028 fun elabHead env infer (e as (_, loc)) t = |
1100 let | 1029 let |
1101 fun unravel (t, e) = | 1030 fun unravel (t, e) = |
1102 let | 1031 case hnormCon env t of |
1103 val (t, gs) = hnormCon (env, denv) t | 1032 (L'.TKFun (x, t'), _) => |
1104 in | 1033 let |
1105 case t of | 1034 val u = kunif loc |
1106 (L'.TKFun (x, t'), _) => | 1035 |
1107 let | 1036 val t'' = subKindInCon (0, u) t' |
1108 val u = kunif loc | 1037 in |
1109 | 1038 unravel (t'', (L'.EKApp (e, u), loc)) |
1110 val t'' = subKindInCon (0, u) t' | 1039 end |
1111 val (e, t, gs') = unravel (t'', (L'.EKApp (e, u), loc)) | 1040 | (L'.TCFun (L'.Implicit, x, k, t'), _) => |
1112 in | 1041 let |
1113 (e, t, enD gs @ gs') | 1042 val u = cunif (loc, k) |
1114 end | 1043 |
1115 | (L'.TCFun (L'.Implicit, x, k, t'), _) => | 1044 val t'' = subConInCon (0, u) t' |
1116 let | 1045 in |
1117 val u = cunif (loc, k) | 1046 unravel (t'', (L'.ECApp (e, u), loc)) |
1118 | 1047 end |
1119 val t'' = subConInCon (0, u) t' | 1048 | (L'.TFun (dom as (L'.CApp (cl, _), _), ran), _) => |
1120 val (e, t, gs') = unravel (t'', (L'.ECApp (e, u), loc)) | 1049 let |
1121 in | 1050 val cl = hnormCon env cl |
1122 (*prefaces "Unravel" [("t'", p_con env t'), | 1051 in |
1123 ("t''", p_con env t'')];*) | 1052 if infer <> L.TypesOnly andalso E.isClass env cl then |
1124 (e, t, enD gs @ gs') | 1053 let |
1125 end | 1054 val r = ref NONE |
1126 | (L'.TFun (dom as (L'.CApp (cl, _), _), ran), _) => | 1055 val (e, t, gs) = unravel (ran, (L'.EApp (e, (L'.EUnif r, loc)), loc)) |
1127 let | 1056 in |
1128 val cl = #1 (hnormCon (env, denv) cl) | 1057 (e, t, TypeClass (env, dom, r, loc) :: gs) |
1129 in | 1058 end |
1130 if infer <> L.TypesOnly andalso E.isClass env cl then | 1059 else |
1131 let | 1060 (e, t, []) |
1132 val r = ref NONE | 1061 end |
1133 val (e, t, gs') = unravel (ran, (L'.EApp (e, (L'.EUnif r, loc)), loc)) | 1062 | t => (e, t, []) |
1134 in | |
1135 (e, t, TypeClass (env, dom, r, loc) :: enD gs @ gs') | |
1136 end | |
1137 else | |
1138 (e, t, enD gs) | |
1139 end | |
1140 | _ => (e, t, enD gs) | |
1141 end | |
1142 in | 1063 in |
1143 case infer of | 1064 case infer of |
1144 L.DontInfer => (e, t, []) | 1065 L.DontInfer => (e, t, []) |
1145 | _ => unravel (t, e) | 1066 | _ => unravel (t, e) |
1146 end | 1067 end |
1147 | 1068 |
1148 fun elabPat (pAll as (p, loc), (env, denv, bound)) = | 1069 fun elabPat (pAll as (p, loc), (env, bound)) = |
1149 let | 1070 let |
1150 val perror = (L'.PWild, loc) | 1071 val perror = (L'.PWild, loc) |
1151 val terror = (L'.CError, loc) | 1072 val terror = (L'.CError, loc) |
1152 val pterror = (perror, terror) | 1073 val pterror = (perror, terror) |
1153 val rerror = (pterror, (env, bound)) | 1074 val rerror = (pterror, (env, bound)) |
1167 (((L'.PCon (dk, pc, unifs, NONE), loc), dn), | 1088 (((L'.PCon (dk, pc, unifs, NONE), loc), dn), |
1168 (env, bound)) | 1089 (env, bound)) |
1169 end | 1090 end |
1170 | (SOME p, SOME t) => | 1091 | (SOME p, SOME t) => |
1171 let | 1092 let |
1172 val ((p', pt), (env, bound)) = elabPat (p, (env, denv, bound)) | 1093 val ((p', pt), (env, bound)) = elabPat (p, (env, bound)) |
1173 | 1094 |
1174 val k = (L'.KType, loc) | 1095 val k = (L'.KType, loc) |
1175 val unifs = map (fn _ => cunif (loc, k)) xs | 1096 val unifs = map (fn _ => cunif (loc, k)) xs |
1176 val nxs = length unifs - 1 | 1097 val nxs = length unifs - 1 |
1177 val t = ListUtil.foldli (fn (i, u, t) => subConInCon (nxs - i, u) t) t unifs | 1098 val t = ListUtil.foldli (fn (i, u, t) => subConInCon (nxs - i, u) t) t unifs |
1178 val dn = foldl (fn (u, dn) => (L'.CApp (dn, u), loc)) dn unifs | 1099 val dn = foldl (fn (u, dn) => (L'.CApp (dn, u), loc)) dn unifs |
1179 in | 1100 in |
1180 ignore (checkPatCon (env, denv) p' pt t); | 1101 ignore (checkPatCon env p' pt t); |
1181 (((L'.PCon (dk, pc, unifs, SOME p'), loc), dn), | 1102 (((L'.PCon (dk, pc, unifs, SOME p'), loc), dn), |
1182 (env, bound)) | 1103 (env, bound)) |
1183 end | 1104 end |
1184 in | 1105 in |
1185 case p of | 1106 case p of |
1224 | L.PRecord (xps, flex) => | 1145 | L.PRecord (xps, flex) => |
1225 let | 1146 let |
1226 val (xpts, (env, bound, _)) = | 1147 val (xpts, (env, bound, _)) = |
1227 ListUtil.foldlMap (fn ((x, p), (env, bound, fbound)) => | 1148 ListUtil.foldlMap (fn ((x, p), (env, bound, fbound)) => |
1228 let | 1149 let |
1229 val ((p', t), (env, bound)) = elabPat (p, (env, denv, bound)) | 1150 val ((p', t), (env, bound)) = elabPat (p, (env, bound)) |
1230 in | 1151 in |
1231 if SS.member (fbound, x) then | 1152 if SS.member (fbound, x) then |
1232 expError env (DuplicatePatField (loc, x)) | 1153 expError env (DuplicatePatField (loc, x)) |
1233 else | 1154 else |
1234 (); | 1155 (); |
1262 Wild => "Wild" | 1183 Wild => "Wild" |
1263 | None => "None" | 1184 | None => "None" |
1264 | Datatype _ => "Datatype" | 1185 | Datatype _ => "Datatype" |
1265 | Record _ => "Record" | 1186 | Record _ => "Record" |
1266 | 1187 |
1267 fun exhaustive (env, denv, t, ps) = | 1188 fun exhaustive (env, t, ps) = |
1268 let | 1189 let |
1269 fun depth (p, _) = | 1190 fun depth (p, _) = |
1270 case p of | 1191 case p of |
1271 L'.PWild => 0 | 1192 L'.PWild => 0 |
1272 | L'.PVar _ => 0 | 1193 | L'.PVar _ => 0 |
1329 case to of | 1250 case to of |
1330 NONE => [Datatype (IM.insert (IM.empty, n, Wild))] | 1251 NONE => [Datatype (IM.insert (IM.empty, n, Wild))] |
1331 | SOME t => map (fn c => Datatype (IM.insert (IM.empty, n, c))) | 1252 | SOME t => map (fn c => Datatype (IM.insert (IM.empty, n, c))) |
1332 (enumerateCases (depth-1) t)) cons | 1253 (enumerateCases (depth-1) t)) cons |
1333 in | 1254 in |
1334 case #1 (#1 (hnormCon (env, denv) t)) of | 1255 case #1 (hnormCon env t) of |
1335 L'.CNamed n => | 1256 L'.CNamed n => |
1336 (let | 1257 (let |
1337 val dt = E.lookupDatatype env n | 1258 val dt = E.lookupDatatype env n |
1338 val cons = E.constructors dt | 1259 val cons = E.constructors dt |
1339 in | 1260 in |
1340 dtype cons | 1261 dtype cons |
1341 end handle E.UnboundNamed _ => [Wild]) | 1262 end handle E.UnboundNamed _ => [Wild]) |
1342 | L'.TRecord c => | 1263 | L'.TRecord c => |
1343 (case #1 (#1 (hnormCon (env, denv) c)) of | 1264 (case #1 (hnormCon env c) of |
1344 L'.CRecord (_, xts) => | 1265 L'.CRecord (_, xts) => |
1345 let | 1266 let |
1346 val xts = map (fn (x, t) => (#1 (hnormCon (env, denv) x), t)) xts | 1267 val xts = map (fn (x, t) => (hnormCon env x, t)) xts |
1347 | 1268 |
1348 fun exponentiate fs = | 1269 fun exponentiate fs = |
1349 case fs of | 1270 case fs of |
1350 [] => [SM.empty] | 1271 [] => [SM.empty] |
1351 | ((L'.CName x, _), t) :: rest => | 1272 | ((L'.CName x, _), t) :: rest => |
1403 r | 1324 r |
1404 end | 1325 end |
1405 | 1326 |
1406 fun isTotal (c, t) = | 1327 fun isTotal (c, t) = |
1407 case c of | 1328 case c of |
1408 None => (false, []) | 1329 None => false |
1409 | Wild => (true, []) | 1330 | Wild => true |
1410 | Datatype cm => | 1331 | Datatype cm => |
1411 let | 1332 let |
1412 val ((t, _), gs) = hnormCon (env, denv) t | 1333 val (t, _) = hnormCon env t |
1413 | 1334 |
1414 fun dtype cons = | 1335 val dtype = |
1415 foldl (fn ((_, n, to), (total, gs)) => | 1336 List.all (fn (_, n, to) => |
1416 case IM.find (cm, n) of | 1337 case IM.find (cm, n) of |
1417 NONE => (false, gs) | 1338 NONE => false |
1418 | SOME c' => | 1339 | SOME c' => |
1419 case to of | 1340 case to of |
1420 NONE => (total, gs) | 1341 NONE => true |
1421 | SOME t' => | 1342 | SOME t' => isTotal (c', t')) |
1422 let | |
1423 val (total, gs') = isTotal (c', t') | |
1424 in | |
1425 (total, gs' @ gs) | |
1426 end) | |
1427 (true, gs) cons | |
1428 | 1343 |
1429 fun unapp t = | 1344 fun unapp t = |
1430 case t of | 1345 case t of |
1431 L'.CApp ((t, _), _) => unapp t | 1346 L'.CApp ((t, _), _) => unapp t |
1432 | _ => t | 1347 | _ => t |
1445 in | 1360 in |
1446 case E.projectDatatype env {str = str, sgn = sgn, field = x} of | 1361 case E.projectDatatype env {str = str, sgn = sgn, field = x} of |
1447 NONE => raise Fail "isTotal: Can't project datatype" | 1362 NONE => raise Fail "isTotal: Can't project datatype" |
1448 | SOME (_, cons) => dtype cons | 1363 | SOME (_, cons) => dtype cons |
1449 end | 1364 end |
1450 | L'.CError => (true, gs) | 1365 | L'.CError => true |
1451 | c => | 1366 | c => |
1452 (prefaces "Not a datatype" [("c", p_con env (c, ErrorMsg.dummySpan))]; | 1367 (prefaces "Not a datatype" [("c", p_con env (c, ErrorMsg.dummySpan))]; |
1453 raise Fail "isTotal: Not a datatype") | 1368 raise Fail "isTotal: Not a datatype") |
1454 end | 1369 end |
1455 | Record _ => (List.all (fn c2 => coverageImp (c, c2)) (enumerateCases depth t), []) | 1370 | Record _ => List.all (fn c2 => coverageImp (c, c2)) (enumerateCases depth t) |
1456 in | 1371 in |
1457 isTotal (combinedCoverage ps, t) | 1372 isTotal (combinedCoverage ps, t) |
1458 end | 1373 end |
1459 | 1374 |
1460 fun unmodCon env (c, loc) = | 1375 fun unmodCon env (c, loc) = |
1474 end | 1389 end |
1475 | _ => (c, loc) | 1390 | _ => (c, loc) |
1476 | 1391 |
1477 fun normClassKey envs c = | 1392 fun normClassKey envs c = |
1478 let | 1393 let |
1479 val c = ElabOps.hnormCon envs c | 1394 val c = hnormCon envs c |
1480 in | 1395 in |
1481 case #1 c of | 1396 case #1 c of |
1482 L'.CApp (c1, c2) => | 1397 L'.CApp (c1, c2) => |
1483 let | 1398 let |
1484 val c1 = normClassKey envs c1 | 1399 val c1 = normClassKey envs c1 |
1499 (L'.CApp (f, x), loc) | 1414 (L'.CApp (f, x), loc) |
1500 end | 1415 end |
1501 | L'.CUnif (_, _, _, ref (SOME c)) => normClassConstraint env c | 1416 | L'.CUnif (_, _, _, ref (SOME c)) => normClassConstraint env c |
1502 | _ => (c, loc) | 1417 | _ => (c, loc) |
1503 | 1418 |
1504 | |
1505 val makeInstantiable = | |
1506 let | |
1507 fun kind k = k | |
1508 fun con c = | |
1509 case c of | |
1510 L'.CDisjoint (L'.LeaveAlone, c1, c2, c) => L'.CDisjoint (L'.Instantiate, c1, c2, c) | |
1511 | _ => c | |
1512 in | |
1513 U.Con.map {kind = kind, con = con} | |
1514 end | |
1515 | |
1516 fun elabExp (env, denv) (eAll as (e, loc)) = | 1419 fun elabExp (env, denv) (eAll as (e, loc)) = |
1517 let | 1420 let |
1518 (*val () = eprefaces "elabExp" [("eAll", SourcePrint.p_exp eAll)];*) | 1421 (*val () = eprefaces "elabExp" [("eAll", SourcePrint.p_exp eAll)];*) |
1519 (*val befor = Time.now ()*) | 1422 (*val befor = Time.now ()*) |
1520 | 1423 |
1521 val r = case e of | 1424 val r = case e of |
1522 L.EAnnot (e, t) => | 1425 L.EAnnot (e, t) => |
1523 let | 1426 let |
1524 val (e', et, gs1) = elabExp (env, denv) e | 1427 val (e', et, gs1) = elabExp (env, denv) e |
1525 val (t', _, gs2) = elabCon (env, denv) t | 1428 val (t', _, gs2) = elabCon (env, denv) t |
1526 val gs3 = checkCon (env, denv) e' et t' | |
1527 in | 1429 in |
1528 (e', t', gs1 @ enD gs2 @ enD gs3) | 1430 checkCon env e' et t'; |
1431 (e', t', gs1 @ enD gs2) | |
1529 end | 1432 end |
1530 | 1433 |
1531 | L.EPrim p => ((L'.EPrim p, loc), primType env p, []) | 1434 | L.EPrim p => ((L'.EPrim p, loc), primType env p, []) |
1532 | L.EVar ([], s, infer) => | 1435 | L.EVar ([], s, infer) => |
1533 (case E.lookupE env s of | 1436 (case E.lookupE env s of |
1534 E.NotBound => | 1437 E.NotBound => |
1535 (expError env (UnboundExp (loc, s)); | 1438 (expError env (UnboundExp (loc, s)); |
1536 (eerror, cerror, [])) | 1439 (eerror, cerror, [])) |
1537 | E.Rel (n, t) => elabHead (env, denv) infer (L'.ERel n, loc) t | 1440 | E.Rel (n, t) => elabHead env infer (L'.ERel n, loc) t |
1538 | E.Named (n, t) => elabHead (env, denv) infer (L'.ENamed n, loc) t) | 1441 | E.Named (n, t) => elabHead env infer (L'.ENamed n, loc) t) |
1539 | L.EVar (m1 :: ms, s, infer) => | 1442 | L.EVar (m1 :: ms, s, infer) => |
1540 (case E.lookupStr env m1 of | 1443 (case E.lookupStr env m1 of |
1541 NONE => (expError env (UnboundStrInExp (loc, m1)); | 1444 NONE => (expError env (UnboundStrInExp (loc, m1)); |
1542 (eerror, cerror, [])) | 1445 (eerror, cerror, [])) |
1543 | SOME (n, sgn) => | 1446 | SOME (n, sgn) => |
1552 val t = case E.projectVal env {sgn = sgn, str = str, field = s} of | 1455 val t = case E.projectVal env {sgn = sgn, str = str, field = s} of |
1553 NONE => (expError env (UnboundExp (loc, s)); | 1456 NONE => (expError env (UnboundExp (loc, s)); |
1554 cerror) | 1457 cerror) |
1555 | SOME t => t | 1458 | SOME t => t |
1556 in | 1459 in |
1557 elabHead (env, denv) infer (L'.EModProj (n, ms, s), loc) t | 1460 elabHead env infer (L'.EModProj (n, ms, s), loc) t |
1558 end) | 1461 end) |
1559 | 1462 |
1560 | L.EWild => | 1463 | L.EWild => |
1561 let | 1464 let |
1562 val r = ref NONE | 1465 val r = ref NONE |
1571 val (e2', t2, gs2) = elabExp (env, denv) e2 | 1474 val (e2', t2, gs2) = elabExp (env, denv) e2 |
1572 | 1475 |
1573 val dom = cunif (loc, ktype) | 1476 val dom = cunif (loc, ktype) |
1574 val ran = cunif (loc, ktype) | 1477 val ran = cunif (loc, ktype) |
1575 val t = (L'.TFun (dom, ran), dummy) | 1478 val t = (L'.TFun (dom, ran), dummy) |
1576 | |
1577 val gs3 = checkCon (env, denv) e1' t1 t | |
1578 val gs4 = checkCon (env, denv) e2' t2 dom | |
1579 | |
1580 val gs = gs1 @ gs2 @ enD gs3 @ enD gs4 | |
1581 in | 1479 in |
1582 ((L'.EApp (e1', e2'), loc), ran, gs) | 1480 checkCon env e1' t1 t; |
1481 checkCon env e2' t2 dom; | |
1482 ((L'.EApp (e1', e2'), loc), ran, gs1 @ gs2) | |
1583 end | 1483 end |
1584 | L.EAbs (x, to, e) => | 1484 | L.EAbs (x, to, e) => |
1585 let | 1485 let |
1586 val (t', gs1) = case to of | 1486 val (t', gs1) = case to of |
1587 NONE => (cunif (loc, ktype), []) | 1487 NONE => (cunif (loc, ktype), []) |
1602 | L.ECApp (e, c) => | 1502 | L.ECApp (e, c) => |
1603 let | 1503 let |
1604 val (e', et, gs1) = elabExp (env, denv) e | 1504 val (e', et, gs1) = elabExp (env, denv) e |
1605 val oldEt = et | 1505 val oldEt = et |
1606 val (c', ck, gs2) = elabCon (env, denv) c | 1506 val (c', ck, gs2) = elabCon (env, denv) c |
1607 val ((et', _), gs3) = hnormCon (env, denv) et | 1507 val (et', _) = hnormCon env et |
1608 in | 1508 in |
1609 case et' of | 1509 case et' of |
1610 L'.CError => (eerror, cerror, []) | 1510 L'.CError => (eerror, cerror, []) |
1611 | L'.TCFun (_, x, k, eb) => | 1511 | L'.TCFun (_, x, k, eb) => |
1612 let | 1512 let |
1619 ("et", p_con env oldEt), | 1519 ("et", p_con env oldEt), |
1620 ("x", PD.string x), | 1520 ("x", PD.string x), |
1621 ("eb", p_con (E.pushCRel env x k) eb), | 1521 ("eb", p_con (E.pushCRel env x k) eb), |
1622 ("c", p_con env c'), | 1522 ("c", p_con env c'), |
1623 ("eb'", p_con env eb')];*) | 1523 ("eb'", p_con env eb')];*) |
1624 ((L'.ECApp (e', c'), loc), eb', gs1 @ enD gs2 @ enD gs3) | 1524 ((L'.ECApp (e', c'), loc), eb', gs1 @ enD gs2) |
1625 end | 1525 end |
1626 | 1526 |
1627 | _ => | 1527 | _ => |
1628 (expError env (WrongForm ("constructor function", e', et)); | 1528 (expError env (WrongForm ("constructor function", e', et)); |
1629 (eerror, cerror, [])) | 1529 (eerror, cerror, [])) |
1656 val (c2', k2, gs2) = elabCon (env, denv) c2 | 1556 val (c2', k2, gs2) = elabCon (env, denv) c2 |
1657 | 1557 |
1658 val ku1 = kunif loc | 1558 val ku1 = kunif loc |
1659 val ku2 = kunif loc | 1559 val ku2 = kunif loc |
1660 | 1560 |
1661 val (denv', gs3) = D.assert env denv (c1', c2') | 1561 val denv' = D.assert env denv (c1', c2') |
1662 val (e', t, gs4) = elabExp (env, denv') e | 1562 val (e', t, gs3) = elabExp (env, denv') e |
1663 in | 1563 in |
1664 checkKind env c1' k1 (L'.KRecord ku1, loc); | 1564 checkKind env c1' k1 (L'.KRecord ku1, loc); |
1665 checkKind env c2' k2 (L'.KRecord ku2, loc); | 1565 checkKind env c2' k2 (L'.KRecord ku2, loc); |
1666 | 1566 |
1667 (e', (L'.CDisjoint (L'.LeaveAlone, c1', c2', t), loc), enD gs1 @ enD gs2 @ enD gs3 @ gs4) | 1567 (e', (L'.TDisjoint (c1', c2', t), loc), enD gs1 @ enD gs2 @ gs3) |
1668 end | 1568 end |
1669 | 1569 |
1670 | L.ERecord xes => | 1570 | L.ERecord xes => |
1671 let | 1571 let |
1672 val (xes', gs) = ListUtil.foldlMap (fn ((x, e), gs) => | 1572 val (xes', gs) = ListUtil.foldlMap (fn ((x, e), gs) => |
1716 | 1616 |
1717 val ft = cunif (loc, ktype) | 1617 val ft = cunif (loc, ktype) |
1718 val rest = cunif (loc, ktype_record) | 1618 val rest = cunif (loc, ktype_record) |
1719 val first = (L'.CRecord (ktype, [(c', ft)]), loc) | 1619 val first = (L'.CRecord (ktype, [(c', ft)]), loc) |
1720 | 1620 |
1721 val gs3 = | 1621 val gs3 = D.prove env denv (first, rest, loc) |
1722 checkCon (env, denv) e' et | |
1723 (L'.TRecord (L'.CConcat (first, rest), loc), loc) | |
1724 val gs4 = D.prove env denv (first, rest, loc) | |
1725 in | 1622 in |
1726 ((L'.EField (e', c', {field = ft, rest = rest}), loc), ft, gs1 @ enD gs2 @ enD gs3 @ enD gs4) | 1623 checkCon env e' et |
1624 (L'.TRecord (L'.CConcat (first, rest), loc), loc); | |
1625 ((L'.EField (e', c', {field = ft, rest = rest}), loc), ft, gs1 @ enD gs2 @ enD gs3) | |
1727 end | 1626 end |
1728 | 1627 |
1729 | L.EConcat (e1, e2) => | 1628 | L.EConcat (e1, e2) => |
1730 let | 1629 let |
1731 val (e1', e1t, gs1) = elabExp (env, denv) e1 | 1630 val (e1', e1t, gs1) = elabExp (env, denv) e1 |
1732 val (e2', e2t, gs2) = elabExp (env, denv) e2 | 1631 val (e2', e2t, gs2) = elabExp (env, denv) e2 |
1733 | 1632 |
1734 val r1 = cunif (loc, ktype_record) | 1633 val r1 = cunif (loc, ktype_record) |
1735 val r2 = cunif (loc, ktype_record) | 1634 val r2 = cunif (loc, ktype_record) |
1736 | 1635 |
1737 val gs3 = checkCon (env, denv) e1' e1t (L'.TRecord r1, loc) | 1636 val gs3 = D.prove env denv (r1, r2, loc) |
1738 val gs4 = checkCon (env, denv) e2' e2t (L'.TRecord r2, loc) | |
1739 val gs5 = D.prove env denv (r1, r2, loc) | |
1740 in | 1637 in |
1638 checkCon env e1' e1t (L'.TRecord r1, loc); | |
1639 checkCon env e2' e2t (L'.TRecord r2, loc); | |
1741 ((L'.EConcat (e1', r1, e2', r2), loc), | 1640 ((L'.EConcat (e1', r1, e2', r2), loc), |
1742 (L'.TRecord ((L'.CConcat (r1, r2), loc)), loc), | 1641 (L'.TRecord ((L'.CConcat (r1, r2), loc)), loc), |
1743 gs1 @ gs2 @ enD gs3 @ enD gs4 @ enD gs5) | 1642 gs1 @ gs2 @ enD gs3) |
1744 end | 1643 end |
1745 | L.ECut (e, c) => | 1644 | L.ECut (e, c) => |
1746 let | 1645 let |
1747 val (e', et, gs1) = elabExp (env, denv) e | 1646 val (e', et, gs1) = elabExp (env, denv) e |
1748 val (c', ck, gs2) = elabCon (env, denv) c | 1647 val (c', ck, gs2) = elabCon (env, denv) c |
1749 | 1648 |
1750 val ft = cunif (loc, ktype) | 1649 val ft = cunif (loc, ktype) |
1751 val rest = cunif (loc, ktype_record) | 1650 val rest = cunif (loc, ktype_record) |
1752 val first = (L'.CRecord (ktype, [(c', ft)]), loc) | 1651 val first = (L'.CRecord (ktype, [(c', ft)]), loc) |
1753 | 1652 |
1754 val gs3 = | 1653 val gs3 = D.prove env denv (first, rest, loc) |
1755 checkCon (env, denv) e' et | |
1756 (L'.TRecord (L'.CConcat (first, rest), loc), loc) | |
1757 val gs4 = D.prove env denv (first, rest, loc) | |
1758 in | 1654 in |
1655 checkCon env e' et | |
1656 (L'.TRecord (L'.CConcat (first, rest), loc), loc); | |
1759 ((L'.ECut (e', c', {field = ft, rest = rest}), loc), (L'.TRecord rest, loc), | 1657 ((L'.ECut (e', c', {field = ft, rest = rest}), loc), (L'.TRecord rest, loc), |
1760 gs1 @ enD gs2 @ enD gs3 @ enD gs4) | 1658 gs1 @ enD gs2 @ enD gs3) |
1761 end | 1659 end |
1762 | L.ECutMulti (e, c) => | 1660 | L.ECutMulti (e, c) => |
1763 let | 1661 let |
1764 val (e', et, gs1) = elabExp (env, denv) e | 1662 val (e', et, gs1) = elabExp (env, denv) e |
1765 val (c', ck, gs2) = elabCon (env, denv) c | 1663 val (c', ck, gs2) = elabCon (env, denv) c |
1766 | 1664 |
1767 val rest = cunif (loc, ktype_record) | 1665 val rest = cunif (loc, ktype_record) |
1768 | 1666 |
1769 val gs3 = | 1667 val gs3 = D.prove env denv (c', rest, loc) |
1770 checkCon (env, denv) e' et | |
1771 (L'.TRecord (L'.CConcat (c', rest), loc), loc) | |
1772 val gs4 = D.prove env denv (c', rest, loc) | |
1773 in | 1668 in |
1669 checkCon env e' et | |
1670 (L'.TRecord (L'.CConcat (c', rest), loc), loc); | |
1774 ((L'.ECutMulti (e', c', {rest = rest}), loc), (L'.TRecord rest, loc), | 1671 ((L'.ECutMulti (e', c', {rest = rest}), loc), (L'.TRecord rest, loc), |
1775 gs1 @ enD gs2 @ enD gs3 @ enD gs4) | 1672 gs1 @ enD gs2 @ enD gs3) |
1776 end | 1673 end |
1777 | 1674 |
1778 | L.ECase (e, pes) => | 1675 | L.ECase (e, pes) => |
1779 let | 1676 let |
1780 val (e', et, gs1) = elabExp (env, denv) e | 1677 val (e', et, gs1) = elabExp (env, denv) e |
1781 val result = cunif (loc, (L'.KType, loc)) | 1678 val result = cunif (loc, (L'.KType, loc)) |
1782 val (pes', gs) = ListUtil.foldlMap | 1679 val (pes', gs) = ListUtil.foldlMap |
1783 (fn ((p, e), gs) => | 1680 (fn ((p, e), gs) => |
1784 let | 1681 let |
1785 val ((p', pt), (env, _)) = elabPat (p, (env, denv, SS.empty)) | 1682 val ((p', pt), (env, _)) = elabPat (p, (env, SS.empty)) |
1786 | 1683 |
1787 val gs1 = checkPatCon (env, denv) p' pt et | 1684 val (e', et, gs1) = elabExp (env, denv) e |
1788 val (e', et, gs2) = elabExp (env, denv) e | |
1789 val gs3 = checkCon (env, denv) e' et result | |
1790 in | 1685 in |
1791 ((p', e'), enD gs1 @ gs2 @ enD gs3 @ gs) | 1686 checkPatCon env p' pt et; |
1687 checkCon env e' et result; | |
1688 ((p', e'), gs1 @ gs) | |
1792 end) | 1689 end) |
1793 gs1 pes | 1690 gs1 pes |
1794 | |
1795 val (total, gs') = exhaustive (env, denv, et, map #1 pes') | |
1796 in | 1691 in |
1797 if total then | 1692 if exhaustive (env, et, map #1 pes') then |
1798 () | 1693 () |
1799 else | 1694 else |
1800 expError env (Inexhaustive loc); | 1695 expError env (Inexhaustive loc); |
1801 | 1696 |
1802 ((L'.ECase (e', pes', {disc = et, result = result}), loc), result, enD gs' @ gs) | 1697 ((L'.ECase (e', pes', {disc = et, result = result}), loc), result, gs) |
1803 end | 1698 end |
1804 | 1699 |
1805 | L.ELet (eds, e) => | 1700 | L.ELet (eds, e) => |
1806 let | 1701 let |
1807 val (eds, (env, gs1)) = ListUtil.foldlMap (elabEdecl denv) (env, []) eds | 1702 val (eds, (env, gs1)) = ListUtil.foldlMap (elabEdecl denv) (env, []) eds |
1813 (*prefaces "elabExp" [("e", SourcePrint.p_exp eAll), | 1708 (*prefaces "elabExp" [("e", SourcePrint.p_exp eAll), |
1814 ("t", PD.string (LargeReal.toString (Time.toReal (Time.- (Time.now (), befor)))))];*) | 1709 ("t", PD.string (LargeReal.toString (Time.toReal (Time.- (Time.now (), befor)))))];*) |
1815 r | 1710 r |
1816 end | 1711 end |
1817 | 1712 |
1818 and elabEdecl denv (dAll as (d, loc), (env, gs : constraint list)) = | 1713 and elabEdecl denv (dAll as (d, loc), (env, gs)) = |
1819 let | 1714 let |
1820 val r = | 1715 val r = |
1821 case d of | 1716 case d of |
1822 L.EDVal (x, co, e) => | 1717 L.EDVal (x, co, e) => |
1823 let | 1718 let |
1824 val (c', _, gs1) = case co of | 1719 val (c', _, gs1) = case co of |
1825 NONE => (cunif (loc, ktype), ktype, []) | 1720 NONE => (cunif (loc, ktype), ktype, []) |
1826 | SOME c => elabCon (env, denv) c | 1721 | SOME c => elabCon (env, denv) c |
1827 | 1722 |
1828 val (e', et, gs2) = elabExp (env, denv) e | 1723 val (e', et, gs2) = elabExp (env, denv) e |
1829 val gs3 = checkCon (env, denv) e' et c' | 1724 |
1830 val c' = normClassConstraint env c' | 1725 val c' = normClassConstraint env c' |
1831 val env' = E.pushERel env x c' | 1726 val env' = E.pushERel env x c' |
1832 val c' = makeInstantiable c' | |
1833 in | 1727 in |
1834 ((L'.EDVal (x, c', e'), loc), (env', enD gs1 @ gs2 @ enD gs3 @ gs)) | 1728 checkCon env e' et c'; |
1729 ((L'.EDVal (x, c', e'), loc), (env', enD gs1 @ gs2 @ gs)) | |
1835 end | 1730 end |
1836 | L.EDValRec vis => | 1731 | L.EDValRec vis => |
1837 let | 1732 let |
1838 fun allowable (e, _) = | 1733 fun allowable (e, _) = |
1839 case e of | 1734 case e of |
1856 val env = foldl (fn ((x, c', _), env) => E.pushERel env x c') env vis | 1751 val env = foldl (fn ((x, c', _), env) => E.pushERel env x c') env vis |
1857 | 1752 |
1858 val (vis, gs) = ListUtil.foldlMap (fn ((x, c', e), gs) => | 1753 val (vis, gs) = ListUtil.foldlMap (fn ((x, c', e), gs) => |
1859 let | 1754 let |
1860 val (e', et, gs1) = elabExp (env, denv) e | 1755 val (e', et, gs1) = elabExp (env, denv) e |
1861 | |
1862 val gs2 = checkCon (env, denv) e' et c' | |
1863 | |
1864 val c' = makeInstantiable c' | |
1865 in | 1756 in |
1757 checkCon env e' et c'; | |
1866 if allowable e then | 1758 if allowable e then |
1867 () | 1759 () |
1868 else | 1760 else |
1869 expError env (IllegalRec (x, e')); | 1761 expError env (IllegalRec (x, e')); |
1870 ((x, c', e'), gs1 @ enD gs2 @ gs) | 1762 ((x, c', e'), gs1 @ gs) |
1871 end) gs vis | 1763 end) gs vis |
1872 in | 1764 in |
1873 ((L'.EDValRec vis, loc), (env, gs)) | 1765 ((L'.EDValRec vis, loc), (env, gs)) |
1874 end | 1766 end |
1875 in | 1767 in |
1894 (strerror, sgnerror)) | 1786 (strerror, sgnerror)) |
1895 | SOME sgn => ((L'.StrProj (str, m), loc), sgn)) | 1787 | SOME sgn => ((L'.StrProj (str, m), loc), sgn)) |
1896 ((L'.StrVar n, loc), sgn) strs | 1788 ((L'.StrVar n, loc), sgn) strs |
1897 | 1789 |
1898 val cso = E.projectConstraints env {sgn = sgn, str = st} | 1790 val cso = E.projectConstraints env {sgn = sgn, str = st} |
1899 | |
1900 val denv = case cso of | |
1901 NONE => (strError env (UnboundStr (loc, str)); | |
1902 denv) | |
1903 | SOME cs => foldl (fn ((c1, c2), denv) => | |
1904 let | |
1905 val (denv, gs) = D.assert env denv (c1, c2) | |
1906 in | |
1907 case gs of | |
1908 [] => () | |
1909 | _ => raise Fail "dopenConstraints: Sub-constraints remain"; | |
1910 | |
1911 denv | |
1912 end) denv cs | |
1913 in | 1791 in |
1914 denv | 1792 case cso of |
1793 NONE => (strError env (UnboundStr (loc, str)); | |
1794 denv) | |
1795 | SOME cs => foldl (fn ((c1, c2), denv) => | |
1796 D.assert env denv (c1, c2)) denv cs | |
1915 end | 1797 end |
1916 | 1798 |
1917 fun elabSgn_item ((sgi, loc), (env, denv, gs)) = | 1799 fun elabSgn_item ((sgi, loc), (env, denv, gs)) = |
1918 case sgi of | 1800 case sgi of |
1919 L.SgiConAbs (x, k) => | 1801 L.SgiConAbs (x, k) => |
1995 NONE => (conError env (UnboundStrInCon (loc, m)); | 1877 NONE => (conError env (UnboundStrInCon (loc, m)); |
1996 (strerror, sgnerror)) | 1878 (strerror, sgnerror)) |
1997 | SOME sgn => ((L'.StrProj (str, m), loc), sgn)) | 1879 | SOME sgn => ((L'.StrProj (str, m), loc), sgn)) |
1998 ((L'.StrVar n, loc), sgn) ms | 1880 ((L'.StrVar n, loc), sgn) ms |
1999 in | 1881 in |
2000 case hnormCon (env, denv) (L'.CModProj (n, ms, s), loc) of | 1882 case hnormCon env (L'.CModProj (n, ms, s), loc) of |
2001 ((L'.CModProj (n, ms, s), _), gs) => | 1883 (L'.CModProj (n, ms, s), _) => |
2002 (case E.projectDatatype env {sgn = sgn, str = str, field = s} of | 1884 (case E.projectDatatype env {sgn = sgn, str = str, field = s} of |
2003 NONE => (conError env (UnboundDatatype (loc, s)); | 1885 NONE => (conError env (UnboundDatatype (loc, s)); |
2004 ([], (env, denv, gs))) | 1886 ([], (env, denv, []))) |
2005 | SOME (xs, xncs) => | 1887 | SOME (xs, xncs) => |
2006 let | 1888 let |
2007 val k = (L'.KType, loc) | 1889 val k = (L'.KType, loc) |
2008 val k' = foldl (fn (_, k') => (L'.KArrow (k, k'), loc)) k xs | 1890 val k' = foldl (fn (_, k') => (L'.KArrow (k, k'), loc)) k xs |
2009 | 1891 |
2023 t xs | 1905 t xs |
2024 in | 1906 in |
2025 E.pushENamedAs env x n t | 1907 E.pushENamedAs env x n t |
2026 end) env xncs | 1908 end) env xncs |
2027 in | 1909 in |
2028 ([(L'.SgiDatatypeImp (x, n', n, ms, s, xs, xncs), loc)], (env, denv, gs)) | 1910 ([(L'.SgiDatatypeImp (x, n', n, ms, s, xs, xncs), loc)], (env, denv, [])) |
2029 end) | 1911 end) |
2030 | _ => (strError env (NotDatatype loc); | 1912 | _ => (strError env (NotDatatype loc); |
2031 ([], (env, denv, []))) | 1913 ([], (env, denv, []))) |
2032 end) | 1914 end) |
2033 | 1915 |
2074 | L.SgiConstraint (c1, c2) => | 1956 | L.SgiConstraint (c1, c2) => |
2075 let | 1957 let |
2076 val (c1', k1, gs1) = elabCon (env, denv) c1 | 1958 val (c1', k1, gs1) = elabCon (env, denv) c1 |
2077 val (c2', k2, gs2) = elabCon (env, denv) c2 | 1959 val (c2', k2, gs2) = elabCon (env, denv) c2 |
2078 | 1960 |
2079 val (denv, gs3) = D.assert env denv (c1', c2') | 1961 val denv = D.assert env denv (c1', c2') |
2080 in | 1962 in |
2081 checkKind env c1' k1 (L'.KRecord (kunif loc), loc); | 1963 checkKind env c1' k1 (L'.KRecord (kunif loc), loc); |
2082 checkKind env c2' k2 (L'.KRecord (kunif loc), loc); | 1964 checkKind env c2' k2 (L'.KRecord (kunif loc), loc); |
2083 | 1965 |
2084 ([(L'.SgiConstraint (c1', c2'), loc)], (env, denv, gs1 @ gs2 @ gs3)) | 1966 ([(L'.SgiConstraint (c1', c2'), loc)], (env, denv, gs1 @ gs2)) |
2085 end | 1967 end |
2086 | 1968 |
2087 | L.SgiClassAbs (x, k) => | 1969 | L.SgiClassAbs (x, k) => |
2088 let | 1970 let |
2089 val k = elabKind env k | 1971 val k = elabKind env k |
2278 case self str of | 2160 case self str of |
2279 NONE => sgn | 2161 NONE => sgn |
2280 | SOME (str, strs) => selfify env {sgn = sgn, str = str, strs = strs} | 2162 | SOME (str, strs) => selfify env {sgn = sgn, str = str, strs = strs} |
2281 end | 2163 end |
2282 | 2164 |
2283 fun dopen (env, denv) {str, strs, sgn} = | 2165 fun dopen env {str, strs, sgn} = |
2284 let | 2166 let |
2285 val m = foldl (fn (m, str) => (L'.StrProj (str, m), #2 sgn)) | 2167 val m = foldl (fn (m, str) => (L'.StrProj (str, m), #2 sgn)) |
2286 (L'.StrVar str, #2 sgn) strs | 2168 (L'.StrVar str, #2 sgn) strs |
2287 in | 2169 in |
2288 case #1 (hnormSgn env sgn) of | 2170 case #1 (hnormSgn env sgn) of |
2289 L'.SgnConst sgis => | 2171 L'.SgnConst sgis => |
2290 ListUtil.foldlMap (fn ((sgi, loc), (env', denv')) => | 2172 ListUtil.foldlMap (fn ((sgi, loc), env') => |
2291 let | 2173 let |
2292 val d = | 2174 val d = |
2293 case sgi of | 2175 case sgi of |
2294 L'.SgiConAbs (x, n, k) => | 2176 L'.SgiConAbs (x, n, k) => |
2295 let | 2177 let |
2324 val c = (L'.CModProj (str, strs, x), loc) | 2206 val c = (L'.CModProj (str, strs, x), loc) |
2325 in | 2207 in |
2326 (L'.DCon (x, n, k', c), loc) | 2208 (L'.DCon (x, n, k', c), loc) |
2327 end | 2209 end |
2328 in | 2210 in |
2329 (d, (E.declBinds env' d, denv')) | 2211 (d, E.declBinds env' d) |
2330 end) | 2212 end) |
2331 (env, denv) sgis | 2213 env sgis |
2332 | _ => (strError env (UnOpenable sgn); | 2214 | _ => (strError env (UnOpenable sgn); |
2333 ([], (env, denv))) | 2215 ([], env)) |
2334 end | 2216 end |
2335 | 2217 |
2336 fun sgiOfDecl (d, loc) = | 2218 fun sgiOfDecl (d, loc) = |
2337 case d of | 2219 case d of |
2338 L'.DCon (x, n, k, c) => [(L'.SgiCon (x, n, k, c), loc)] | 2220 L'.DCon (x, n, k, c) => [(L'.SgiCon (x, n, k, c), loc)] |
2349 | L'.DSequence (tn, x, n) => [(L'.SgiVal (x, n, sequenceOf ()), loc)] | 2231 | L'.DSequence (tn, x, n) => [(L'.SgiVal (x, n, sequenceOf ()), loc)] |
2350 | L'.DClass (x, n, k, c) => [(L'.SgiClass (x, n, k, c), loc)] | 2232 | L'.DClass (x, n, k, c) => [(L'.SgiClass (x, n, k, c), loc)] |
2351 | L'.DDatabase _ => [] | 2233 | L'.DDatabase _ => [] |
2352 | L'.DCookie (tn, x, n, c) => [(L'.SgiVal (x, n, (L'.CApp (cookieOf (), c), loc)), loc)] | 2234 | L'.DCookie (tn, x, n, c) => [(L'.SgiVal (x, n, (L'.CApp (cookieOf (), c), loc)), loc)] |
2353 | 2235 |
2354 fun sgiBindsD (env, denv) (sgi, _) = | 2236 fun subSgn env sgn1 (sgn2 as (_, loc2)) = |
2355 case sgi of | |
2356 L'.SgiConstraint (c1, c2) => | |
2357 (case D.assert env denv (c1, c2) of | |
2358 (denv, []) => denv | |
2359 | _ => raise Fail "sgiBindsD: Sub-constraints remain") | |
2360 | _ => denv | |
2361 | |
2362 fun subSgn (env, denv) sgn1 (sgn2 as (_, loc2)) = | |
2363 ((*prefaces "subSgn" [("sgn1", p_sgn env sgn1), | 2237 ((*prefaces "subSgn" [("sgn1", p_sgn env sgn1), |
2364 ("sgn2", p_sgn env sgn2)];*) | 2238 ("sgn2", p_sgn env sgn2)];*) |
2365 case (#1 (hnormSgn env sgn1), #1 (hnormSgn env sgn2)) of | 2239 case (#1 (hnormSgn env sgn1), #1 (hnormSgn env sgn2)) of |
2366 (L'.SgnError, _) => () | 2240 (L'.SgnError, _) => () |
2367 | (_, L'.SgnError) => () | 2241 | (_, L'.SgnError) => () |
2371 (*val () = prefaces "subSgn" [("sgn1", p_sgn env sgn1), | 2245 (*val () = prefaces "subSgn" [("sgn1", p_sgn env sgn1), |
2372 ("sgn2", p_sgn env sgn2), | 2246 ("sgn2", p_sgn env sgn2), |
2373 ("sgis1", p_sgn env (L'.SgnConst sgis1, loc2)), | 2247 ("sgis1", p_sgn env (L'.SgnConst sgis1, loc2)), |
2374 ("sgis2", p_sgn env (L'.SgnConst sgis2, loc2))]*) | 2248 ("sgis2", p_sgn env (L'.SgnConst sgis2, loc2))]*) |
2375 | 2249 |
2376 fun folder (sgi2All as (sgi, loc), (env, denv)) = | 2250 fun folder (sgi2All as (sgi, loc), env) = |
2377 let | 2251 let |
2378 (*val () = prefaces "folder" [("sgis1", p_sgn env (L'.SgnConst sgis1, loc2))]*) | 2252 (*val () = prefaces "folder" [("sgis1", p_sgn env (L'.SgnConst sgis1, loc2))]*) |
2379 | 2253 |
2380 fun seek p = | 2254 fun seek p = |
2381 let | 2255 let |
2382 fun seek (env, denv) ls = | 2256 fun seek env ls = |
2383 case ls of | 2257 case ls of |
2384 [] => (sgnError env (UnmatchedSgi sgi2All); | 2258 [] => (sgnError env (UnmatchedSgi sgi2All); |
2385 (env, denv)) | 2259 env) |
2386 | h :: t => | 2260 | h :: t => |
2387 case p (env, h) of | 2261 case p (env, h) of |
2388 NONE => | 2262 NONE => |
2389 let | 2263 let |
2390 val env = case #1 h of | 2264 val env = case #1 h of |
2398 env | 2272 env |
2399 else | 2273 else |
2400 E.pushCNamedAs env x n k NONE | 2274 E.pushCNamedAs env x n k NONE |
2401 | _ => env | 2275 | _ => env |
2402 in | 2276 in |
2403 seek (E.sgiBinds env h, sgiBindsD (env, denv) h) t | 2277 seek (E.sgiBinds env h) t |
2404 end | 2278 end |
2405 | SOME envs => envs | 2279 | SOME envs => envs |
2406 in | 2280 in |
2407 seek (env, denv) sgis1 | 2281 seek env sgis1 |
2408 end | 2282 end |
2409 in | 2283 in |
2410 case sgi of | 2284 case sgi of |
2411 L'.SgiConAbs (x, n2, k2) => | 2285 L'.SgiConAbs (x, n2, k2) => |
2412 seek (fn (env, sgi1All as (sgi1, _)) => | 2286 seek (fn (env, sgi1All as (sgi1, _)) => |
2420 val env = E.pushCNamedAs env x n1 k1 co1 | 2294 val env = E.pushCNamedAs env x n1 k1 co1 |
2421 in | 2295 in |
2422 SOME (if n1 = n2 then | 2296 SOME (if n1 = n2 then |
2423 env | 2297 env |
2424 else | 2298 else |
2425 E.pushCNamedAs env x n2 k2 (SOME (L'.CNamed n1, loc2)), | 2299 E.pushCNamedAs env x n2 k2 (SOME (L'.CNamed n1, loc2))) |
2426 denv) | |
2427 end | 2300 end |
2428 else | 2301 else |
2429 NONE | 2302 NONE |
2430 in | 2303 in |
2431 case sgi1 of | 2304 case sgi1 of |
2468 val env = if n1 = n2 then | 2341 val env = if n1 = n2 then |
2469 env | 2342 env |
2470 else | 2343 else |
2471 E.pushCNamedAs env x n1 k1 (SOME c1) | 2344 E.pushCNamedAs env x n1 k1 (SOME c1) |
2472 in | 2345 in |
2473 SOME (env, denv) | 2346 SOME env |
2474 end | 2347 end |
2475 in | 2348 in |
2476 (case unifyCons (env, denv) c1 c2 of | 2349 (unifyCons env c1 c2; |
2477 [] => good () | 2350 good ()) |
2478 | _ => NONE) | |
2479 handle CUnify (c1, c2, err) => | 2351 handle CUnify (c1, c2, err) => |
2480 (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)); | 2352 (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)); |
2481 good ()) | 2353 good ()) |
2482 end | 2354 end |
2483 else | 2355 else |
2495 let | 2367 let |
2496 fun found (n1, xs1, xncs1) = | 2368 fun found (n1, xs1, xncs1) = |
2497 let | 2369 let |
2498 fun mismatched ue = | 2370 fun mismatched ue = |
2499 (sgnError env (SgiMismatchedDatatypes (sgi1All, sgi2All, ue)); | 2371 (sgnError env (SgiMismatchedDatatypes (sgi1All, sgi2All, ue)); |
2500 SOME (env, denv)) | 2372 SOME env) |
2501 | 2373 |
2502 val k = (L'.KType, loc) | 2374 val k = (L'.KType, loc) |
2503 val k' = foldl (fn (_, k') => (L'.KArrow (k, k'), loc)) k xs1 | 2375 val k' = foldl (fn (_, k') => (L'.KArrow (k, k'), loc)) k xs1 |
2504 | 2376 |
2505 fun good () = | 2377 fun good () = |
2509 env | 2381 env |
2510 else | 2382 else |
2511 E.pushCNamedAs env x n2 k' | 2383 E.pushCNamedAs env x n2 k' |
2512 (SOME (L'.CNamed n1, loc)) | 2384 (SOME (L'.CNamed n1, loc)) |
2513 in | 2385 in |
2514 SOME (env, denv) | 2386 SOME env |
2515 end | 2387 end |
2516 | 2388 |
2517 val env = E.pushCNamedAs env x n1 k' NONE | 2389 val env = E.pushCNamedAs env x n1 k' NONE |
2518 val env = if n1 = n2 then | 2390 val env = if n1 = n2 then |
2519 env | 2391 env |
2523 fun xncBad ((x1, _, t1), (x2, _, t2)) = | 2395 fun xncBad ((x1, _, t1), (x2, _, t2)) = |
2524 String.compare (x1, x2) <> EQUAL | 2396 String.compare (x1, x2) <> EQUAL |
2525 orelse case (t1, t2) of | 2397 orelse case (t1, t2) of |
2526 (NONE, NONE) => false | 2398 (NONE, NONE) => false |
2527 | (SOME t1, SOME t2) => | 2399 | (SOME t1, SOME t2) => |
2528 not (List.null (unifyCons (env, denv) t1 t2)) | 2400 (unifyCons env t1 t2; false) |
2529 | _ => true | 2401 | _ => true |
2530 in | 2402 in |
2531 (if xs1 <> xs2 | 2403 (if xs1 <> xs2 |
2532 orelse length xncs1 <> length xncs2 | 2404 orelse length xncs1 <> length xncs2 |
2533 orelse ListPair.exists xncBad (xncs1, xncs2) then | 2405 orelse ListPair.exists xncBad (xncs1, xncs2) then |
2565 fun good () = | 2437 fun good () = |
2566 let | 2438 let |
2567 val env = E.pushCNamedAs env x n1 k' (SOME t1) | 2439 val env = E.pushCNamedAs env x n1 k' (SOME t1) |
2568 val env = E.pushCNamedAs env x n2 k' (SOME t2) | 2440 val env = E.pushCNamedAs env x n2 k' (SOME t2) |
2569 in | 2441 in |
2570 SOME (env, denv) | 2442 SOME env |
2571 end | 2443 end |
2572 in | 2444 in |
2573 (case unifyCons (env, denv) t1 t2 of | 2445 (unifyCons env t1 t2; |
2574 [] => good () | 2446 good ()) |
2575 | _ => NONE) | |
2576 handle CUnify (c1, c2, err) => | 2447 handle CUnify (c1, c2, err) => |
2577 (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)); | 2448 (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)); |
2578 good ()) | 2449 good ()) |
2579 end | 2450 end |
2580 else | 2451 else |
2585 | L'.SgiVal (x, n2, c2) => | 2456 | L'.SgiVal (x, n2, c2) => |
2586 seek (fn (env, sgi1All as (sgi1, _)) => | 2457 seek (fn (env, sgi1All as (sgi1, _)) => |
2587 case sgi1 of | 2458 case sgi1 of |
2588 L'.SgiVal (x', n1, c1) => | 2459 L'.SgiVal (x', n1, c1) => |
2589 if x = x' then | 2460 if x = x' then |
2590 ((*prefaces "Pre" [("c1", p_con env c1), | 2461 (unifyCons env c1 c2; |
2591 ("c2", p_con env c2)];*) | 2462 SOME env) |
2592 case unifyCons (env, denv) c1 c2 of | |
2593 [] => SOME (env, denv) | |
2594 | _ => NONE) | |
2595 handle CUnify (c1, c2, err) => | 2463 handle CUnify (c1, c2, err) => |
2596 (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)); | 2464 (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)); |
2597 SOME (env, denv)) | 2465 SOME env) |
2598 else | 2466 else |
2599 NONE | 2467 NONE |
2600 | _ => NONE) | 2468 | _ => NONE) |
2601 | 2469 |
2602 | L'.SgiStr (x, n2, sgn2) => | 2470 | L'.SgiStr (x, n2, sgn2) => |
2603 seek (fn (env, sgi1All as (sgi1, _)) => | 2471 seek (fn (env, sgi1All as (sgi1, _)) => |
2604 case sgi1 of | 2472 case sgi1 of |
2605 L'.SgiStr (x', n1, sgn1) => | 2473 L'.SgiStr (x', n1, sgn1) => |
2606 if x = x' then | 2474 if x = x' then |
2607 let | 2475 let |
2608 val () = subSgn (env, denv) sgn1 sgn2 | 2476 val () = subSgn env sgn1 sgn2 |
2609 val env = E.pushStrNamedAs env x n1 sgn1 | 2477 val env = E.pushStrNamedAs env x n1 sgn1 |
2610 val env = if n1 = n2 then | 2478 val env = if n1 = n2 then |
2611 env | 2479 env |
2612 else | 2480 else |
2613 E.pushStrNamedAs env x n2 | 2481 E.pushStrNamedAs env x n2 |
2614 (selfifyAt env {str = (L'.StrVar n1, #2 sgn2), | 2482 (selfifyAt env {str = (L'.StrVar n1, #2 sgn2), |
2615 sgn = sgn2}) | 2483 sgn = sgn2}) |
2616 in | 2484 in |
2617 SOME (env, denv) | 2485 SOME env |
2618 end | 2486 end |
2619 else | 2487 else |
2620 NONE | 2488 NONE |
2621 | _ => NONE) | 2489 | _ => NONE) |
2622 | 2490 |
2624 seek (fn (env, sgi1All as (sgi1, _)) => | 2492 seek (fn (env, sgi1All as (sgi1, _)) => |
2625 case sgi1 of | 2493 case sgi1 of |
2626 L'.SgiSgn (x', n1, sgn1) => | 2494 L'.SgiSgn (x', n1, sgn1) => |
2627 if x = x' then | 2495 if x = x' then |
2628 let | 2496 let |
2629 val () = subSgn (env, denv) sgn1 sgn2 | 2497 val () = subSgn env sgn1 sgn2 |
2630 val () = subSgn (env, denv) sgn2 sgn1 | 2498 val () = subSgn env sgn2 sgn1 |
2631 | 2499 |
2632 val env = E.pushSgnNamedAs env x n2 sgn2 | 2500 val env = E.pushSgnNamedAs env x n2 sgn2 |
2633 val env = if n1 = n2 then | 2501 val env = if n1 = n2 then |
2634 env | 2502 env |
2635 else | 2503 else |
2636 E.pushSgnNamedAs env x n1 sgn2 | 2504 E.pushSgnNamedAs env x n1 sgn2 |
2637 in | 2505 in |
2638 SOME (env, denv) | 2506 SOME env |
2639 end | 2507 end |
2640 else | 2508 else |
2641 NONE | 2509 NONE |
2642 | _ => NONE) | 2510 | _ => NONE) |
2643 | 2511 |
2644 | L'.SgiConstraint (c2, d2) => | 2512 | L'.SgiConstraint (c2, d2) => |
2645 seek (fn (env, sgi1All as (sgi1, _)) => | 2513 seek (fn (env, sgi1All as (sgi1, _)) => |
2646 case sgi1 of | 2514 case sgi1 of |
2647 L'.SgiConstraint (c1, d1) => | 2515 L'.SgiConstraint (c1, d1) => |
2648 if consEq (env, denv) (c1, c2) andalso consEq (env, denv) (d1, d2) then | 2516 if consEq env (c1, c2) andalso consEq env (d1, d2) then |
2649 let | 2517 SOME env |
2650 val (denv, gs) = D.assert env denv (c2, d2) | |
2651 in | |
2652 case gs of | |
2653 [] => () | |
2654 | _ => raise Fail "subSgn: Sub-constraints remain"; | |
2655 | |
2656 SOME (env, denv) | |
2657 end | |
2658 else | 2518 else |
2659 NONE | 2519 NONE |
2660 | _ => NONE) | 2520 | _ => NONE) |
2661 | 2521 |
2662 | L'.SgiClassAbs (x, n2, k2) => | 2522 | L'.SgiClassAbs (x, n2, k2) => |
2673 val env = E.pushCNamedAs env x n1 k co | 2533 val env = E.pushCNamedAs env x n1 k co |
2674 in | 2534 in |
2675 SOME (if n1 = n2 then | 2535 SOME (if n1 = n2 then |
2676 env | 2536 env |
2677 else | 2537 else |
2678 E.pushCNamedAs env x n2 k (SOME (L'.CNamed n1, loc2)), | 2538 E.pushCNamedAs env x n2 k (SOME (L'.CNamed n1, loc2))) |
2679 denv) | |
2680 end | 2539 end |
2681 else | 2540 else |
2682 NONE | 2541 NONE |
2683 in | 2542 in |
2684 case sgi1 of | 2543 case sgi1 of |
2704 val env = if n1 = n2 then | 2563 val env = if n1 = n2 then |
2705 env | 2564 env |
2706 else | 2565 else |
2707 E.pushCNamedAs env x n1 k (SOME c1) | 2566 E.pushCNamedAs env x n1 k (SOME c1) |
2708 in | 2567 in |
2709 SOME (env, denv) | 2568 SOME env |
2710 end | 2569 end |
2711 in | 2570 in |
2712 (case unifyCons (env, denv) c1 c2 of | 2571 (unifyCons env c1 c2; |
2713 [] => good () | 2572 good ()) |
2714 | _ => NONE) | |
2715 handle CUnify (c1, c2, err) => | 2573 handle CUnify (c1, c2, err) => |
2716 (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)); | 2574 (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)); |
2717 good ()) | 2575 good ()) |
2718 end | 2576 end |
2719 else | 2577 else |
2723 L'.SgiClass (x', n1, k1, c1) => found (x', n1, k1, c1) | 2581 L'.SgiClass (x', n1, k1, c1) => found (x', n1, k1, c1) |
2724 | _ => NONE | 2582 | _ => NONE |
2725 end) | 2583 end) |
2726 end | 2584 end |
2727 in | 2585 in |
2728 ignore (foldl folder (env, denv) sgis2) | 2586 ignore (foldl folder env sgis2) |
2729 end | 2587 end |
2730 | 2588 |
2731 | (L'.SgnFun (m1, n1, dom1, ran1), L'.SgnFun (m2, n2, dom2, ran2)) => | 2589 | (L'.SgnFun (m1, n1, dom1, ran1), L'.SgnFun (m2, n2, dom2, ran2)) => |
2732 let | 2590 let |
2733 val ran2 = | 2591 val ran2 = |
2734 if n1 = n2 then | 2592 if n1 = n2 then |
2735 ran2 | 2593 ran2 |
2736 else | 2594 else |
2737 subStrInSgn (n2, n1) ran2 | 2595 subStrInSgn (n2, n1) ran2 |
2738 in | 2596 in |
2739 subSgn (env, denv) dom2 dom1; | 2597 subSgn env dom2 dom1; |
2740 subSgn (E.pushStrNamedAs env m1 n1 dom2, denv) ran1 ran2 | 2598 subSgn (E.pushStrNamedAs env m1 n1 dom2) ran1 ran2 |
2741 end | 2599 end |
2742 | 2600 |
2743 | _ => sgnError env (SgnWrongForm (sgn1, sgn2))) | 2601 | _ => sgnError env (SgnWrongForm (sgn1, sgn2))) |
2744 | 2602 |
2745 | 2603 |
2757 | 2615 |
2758 | CVar ([], x) => x <> self | 2616 | CVar ([], x) => x <> self |
2759 | CVar _ => true | 2617 | CVar _ => true |
2760 | CApp (c1, c2) => none c1 andalso none c2 | 2618 | CApp (c1, c2) => none c1 andalso none c2 |
2761 | CAbs _ => false | 2619 | CAbs _ => false |
2762 | CDisjoint (c1, c2, c3) => none c1 andalso none c2 andalso none c3 | 2620 | TDisjoint (c1, c2, c3) => none c1 andalso none c2 andalso none c3 |
2763 | 2621 |
2764 | CKAbs _ => false | 2622 | CKAbs _ => false |
2765 | TKFun _ => false | 2623 | TKFun _ => false |
2766 | 2624 |
2767 | CName _ => true | 2625 | CName _ => true |
2786 | TRecord c => pos c | 2644 | TRecord c => pos c |
2787 | 2645 |
2788 | CVar _ => true | 2646 | CVar _ => true |
2789 | CApp (c1, c2) => pos c1 andalso none c2 | 2647 | CApp (c1, c2) => pos c1 andalso none c2 |
2790 | CAbs _ => false | 2648 | CAbs _ => false |
2791 | CDisjoint (c1, c2, c3) => none c1 andalso none c2 andalso none c3 | 2649 | TDisjoint (c1, c2, c3) => none c1 andalso none c2 andalso none c3 |
2792 | 2650 |
2793 | CKAbs _ => false | 2651 | CKAbs _ => false |
2794 | TKFun _ => false | 2652 | TKFun _ => false |
2795 | 2653 |
2796 | CName _ => true | 2654 | CName _ => true |
2969 (L.StrConst (ds @ ds'), #2 str) | 2827 (L.StrConst (ds @ ds'), #2 str) |
2970 end | 2828 end |
2971 | _ => str) | 2829 | _ => str) |
2972 | _ => str | 2830 | _ => str |
2973 | 2831 |
2974 fun elabDecl (dAll as (d, loc), (env, denv, gs : constraint list)) = | 2832 fun elabDecl (dAll as (d, loc), (env, denv, gs)) = |
2975 let | 2833 let |
2976 (*val () = preface ("elabDecl", SourcePrint.p_decl (d, loc))*) | 2834 (*val () = preface ("elabDecl", SourcePrint.p_decl (d, loc))*) |
2977 (*val befor = Time.now ()*) | 2835 (*val befor = Time.now ()*) |
2978 | 2836 |
2979 val r = | 2837 val r = |
3058 NONE => (conError env (UnboundStrInCon (loc, m)); | 2916 NONE => (conError env (UnboundStrInCon (loc, m)); |
3059 (strerror, sgnerror)) | 2917 (strerror, sgnerror)) |
3060 | SOME sgn => ((L'.StrProj (str, m), loc), sgn)) | 2918 | SOME sgn => ((L'.StrProj (str, m), loc), sgn)) |
3061 ((L'.StrVar n, loc), sgn) ms | 2919 ((L'.StrVar n, loc), sgn) ms |
3062 in | 2920 in |
3063 case hnormCon (env, denv) (L'.CModProj (n, ms, s), loc) of | 2921 case hnormCon env (L'.CModProj (n, ms, s), loc) of |
3064 ((L'.CModProj (n, ms, s), _), gs') => | 2922 (L'.CModProj (n, ms, s), _) => |
3065 (case E.projectDatatype env {sgn = sgn, str = str, field = s} of | 2923 (case E.projectDatatype env {sgn = sgn, str = str, field = s} of |
3066 NONE => (conError env (UnboundDatatype (loc, s)); | 2924 NONE => (conError env (UnboundDatatype (loc, s)); |
3067 ([], (env, denv, gs))) | 2925 ([], (env, denv, gs))) |
3068 | SOME (xs, xncs) => | 2926 | SOME (xs, xncs) => |
3069 let | 2927 let |
3085 t xs | 2943 t xs |
3086 in | 2944 in |
3087 E.pushENamedAs env x n t | 2945 E.pushENamedAs env x n t |
3088 end) env xncs | 2946 end) env xncs |
3089 in | 2947 in |
3090 ([(L'.DDatatypeImp (x, n', n, ms, s, xs, xncs), loc)], (env, denv, enD gs' @ gs)) | 2948 ([(L'.DDatatypeImp (x, n', n, ms, s, xs, xncs), loc)], (env, denv, gs)) |
3091 end) | 2949 end) |
3092 | _ => (strError env (NotDatatype loc); | 2950 | _ => (strError env (NotDatatype loc); |
3093 ([], (env, denv, []))) | 2951 ([], (env, denv, []))) |
3094 end) | 2952 end) |
3095 | 2953 |
3098 val (c', _, gs1) = case co of | 2956 val (c', _, gs1) = case co of |
3099 NONE => (cunif (loc, ktype), ktype, []) | 2957 NONE => (cunif (loc, ktype), ktype, []) |
3100 | SOME c => elabCon (env, denv) c | 2958 | SOME c => elabCon (env, denv) c |
3101 | 2959 |
3102 val (e', et, gs2) = elabExp (env, denv) e | 2960 val (e', et, gs2) = elabExp (env, denv) e |
3103 val gs3 = checkCon (env, denv) e' et c' | |
3104 val c = normClassConstraint env c' | 2961 val c = normClassConstraint env c' |
3105 val (env', n) = E.pushENamed env x c' | 2962 val (env', n) = E.pushENamed env x c' |
3106 val c' = makeInstantiable c' | |
3107 in | 2963 in |
2964 checkCon env e' et c'; | |
3108 (*prefaces "DVal" [("x", Print.PD.string x), | 2965 (*prefaces "DVal" [("x", Print.PD.string x), |
3109 ("c'", p_con env c')];*) | 2966 ("c'", p_con env c')];*) |
3110 ([(L'.DVal (x, n, c', e'), loc)], (env', denv, enD gs1 @ gs2 @ enD gs3 @ gs)) | 2967 ([(L'.DVal (x, n, c', e'), loc)], (env', denv, enD gs1 @ gs2 @ gs)) |
3111 end | 2968 end |
3112 | L.DValRec vis => | 2969 | L.DValRec vis => |
3113 let | 2970 let |
3114 fun allowable (e, _) = | 2971 fun allowable (e, _) = |
3115 case e of | 2972 case e of |
3137 end) env vis | 2994 end) env vis |
3138 | 2995 |
3139 val (vis, gs) = ListUtil.foldlMap (fn ((x, n, c', e), gs) => | 2996 val (vis, gs) = ListUtil.foldlMap (fn ((x, n, c', e), gs) => |
3140 let | 2997 let |
3141 val (e', et, gs1) = elabExp (env, denv) e | 2998 val (e', et, gs1) = elabExp (env, denv) e |
3142 | |
3143 val gs2 = checkCon (env, denv) e' et c' | |
3144 | |
3145 val c' = makeInstantiable c' | |
3146 in | 2999 in |
3000 checkCon env e' et c'; | |
3147 if allowable e then | 3001 if allowable e then |
3148 () | 3002 () |
3149 else | 3003 else |
3150 expError env (IllegalRec (x, e')); | 3004 expError env (IllegalRec (x, e')); |
3151 ((x, n, c', e'), gs1 @ enD gs2 @ gs) | 3005 ((x, n, c', e'), gs1 @ gs) |
3152 end) gs vis | 3006 end) gs vis |
3153 in | 3007 in |
3154 ([(L'.DValRec vis, loc)], (env, denv, gs)) | 3008 ([(L'.DValRec vis, loc)], (env, denv, gs)) |
3155 end | 3009 end |
3156 | 3010 |
3182 | SOME (formal, gs1) => | 3036 | SOME (formal, gs1) => |
3183 let | 3037 let |
3184 val str = wildifyStr env (str, formal) | 3038 val str = wildifyStr env (str, formal) |
3185 val (str', actual, gs2) = elabStr (env, denv) str | 3039 val (str', actual, gs2) = elabStr (env, denv) str |
3186 in | 3040 in |
3187 subSgn (env, denv) (selfifyAt env {str = str', sgn = actual}) formal; | 3041 subSgn env (selfifyAt env {str = str', sgn = actual}) formal; |
3188 (str', formal, enD gs1 @ gs2) | 3042 (str', formal, enD gs1 @ gs2) |
3189 end | 3043 end |
3190 | 3044 |
3191 val (env', n) = E.pushStrNamed env x sgn' | 3045 val (env', n) = E.pushStrNamed env x sgn' |
3192 in | 3046 in |
3220 NONE => (strError env (UnboundStr (loc, m)); | 3074 NONE => (strError env (UnboundStr (loc, m)); |
3221 (strerror, sgnerror)) | 3075 (strerror, sgnerror)) |
3222 | SOME sgn => ((L'.StrProj (str, m), loc), sgn)) | 3076 | SOME sgn => ((L'.StrProj (str, m), loc), sgn)) |
3223 ((L'.StrVar n, loc), sgn) ms | 3077 ((L'.StrVar n, loc), sgn) ms |
3224 | 3078 |
3225 val (ds, (env', denv')) = dopen (env, denv) {str = n, strs = ms, sgn = sgn} | 3079 val (ds, env') = dopen env {str = n, strs = ms, sgn = sgn} |
3226 val denv' = dopenConstraints (loc, env', denv') {str = m, strs = ms} | 3080 val denv' = dopenConstraints (loc, env', denv) {str = m, strs = ms} |
3227 in | 3081 in |
3228 (ds, (env', denv', gs)) | 3082 (ds, (env', denv', gs)) |
3229 end) | 3083 end) |
3230 | 3084 |
3231 | L.DConstraint (c1, c2) => | 3085 | L.DConstraint (c1, c2) => |
3232 let | 3086 let |
3233 val (c1', k1, gs1) = elabCon (env, denv) c1 | 3087 val (c1', k1, gs1) = elabCon (env, denv) c1 |
3234 val (c2', k2, gs2) = elabCon (env, denv) c2 | 3088 val (c2', k2, gs2) = elabCon (env, denv) c2 |
3235 val gs3 = D.prove env denv (c1', c2', loc) | 3089 val gs3 = D.prove env denv (c1', c2', loc) |
3236 | 3090 |
3237 val (denv', gs4) = D.assert env denv (c1', c2') | 3091 val denv' = D.assert env denv (c1', c2') |
3238 in | 3092 in |
3239 checkKind env c1' k1 (L'.KRecord (kunif loc), loc); | 3093 checkKind env c1' k1 (L'.KRecord (kunif loc), loc); |
3240 checkKind env c2' k2 (L'.KRecord (kunif loc), loc); | 3094 checkKind env c2' k2 (L'.KRecord (kunif loc), loc); |
3241 | 3095 |
3242 ([(L'.DConstraint (c1', c2'), loc)], (env, denv', enD gs1 @ enD gs2 @ enD gs3 @ enD gs4 @ gs)) | 3096 ([(L'.DConstraint (c1', c2'), loc)], (env, denv', enD gs1 @ enD gs2 @ enD gs3 @ gs)) |
3243 end | 3097 end |
3244 | 3098 |
3245 | L.DOpenConstraints (m, ms) => | 3099 | L.DOpenConstraints (m, ms) => |
3246 let | 3100 let |
3247 val denv = dopenConstraints (loc, env, denv) {str = m, strs = ms} | 3101 val denv = dopenConstraints (loc, env, denv) {str = m, strs = ms} |
3260 fun doOne (all as (sgi, _), env) = | 3114 fun doOne (all as (sgi, _), env) = |
3261 (case sgi of | 3115 (case sgi of |
3262 L'.SgiVal (x, n, t) => | 3116 L'.SgiVal (x, n, t) => |
3263 let | 3117 let |
3264 fun doPage (makeRes, ran) = | 3118 fun doPage (makeRes, ran) = |
3265 case hnormCon (env, denv) ran of | 3119 case hnormCon env ran of |
3266 ((L'.CApp (tf, arg), _), []) => | 3120 (L'.CApp (tf, arg), _) => |
3267 (case (hnormCon (env, denv) tf, hnormCon (env, denv) arg) of | 3121 (case (hnormCon env tf, hnormCon env arg) of |
3268 (((L'.CModProj (basis, [], "transaction"), _), []), | 3122 ((L'.CModProj (basis, [], "transaction"), _), |
3269 ((L'.CApp (tf, arg3), _), [])) => | 3123 (L'.CApp (tf, arg3), _)) => |
3270 (case (basis = !basis_r, | 3124 (case (basis = !basis_r, |
3271 hnormCon (env, denv) tf, hnormCon (env, denv) arg3) of | 3125 hnormCon env tf, hnormCon env arg3) of |
3272 (true, | 3126 (true, |
3273 ((L'.CApp (tf, arg2), _), []), | 3127 (L'.CApp (tf, arg2), _), |
3274 (((L'.CRecord (_, []), _), []))) => | 3128 ((L'.CRecord (_, []), _))) => |
3275 (case (hnormCon (env, denv) tf) of | 3129 (case (hnormCon env tf) of |
3276 ((L'.CApp (tf, arg1), _), []) => | 3130 (L'.CApp (tf, arg1), _) => |
3277 (case (hnormCon (env, denv) tf, | 3131 (case (hnormCon env tf, |
3278 hnormCon (env, denv) arg1, | 3132 hnormCon env arg1, |
3279 hnormCon (env, denv) arg2) of | 3133 hnormCon env arg2) of |
3280 ((tf, []), (arg1, []), | 3134 (tf, arg1, |
3281 ((L'.CRecord (_, []), _), [])) => | 3135 (L'.CRecord (_, []), _)) => |
3282 let | 3136 let |
3283 val t = (L'.CApp (tf, arg1), loc) | 3137 val t = (L'.CApp (tf, arg1), loc) |
3284 val t = (L'.CApp (t, arg2), loc) | 3138 val t = (L'.CApp (t, arg2), loc) |
3285 val t = (L'.CApp (t, arg3), loc) | 3139 val t = (L'.CApp (t, arg3), loc) |
3286 val t = (L'.CApp ( | 3140 val t = (L'.CApp ( |
3294 | _ => all) | 3148 | _ => all) |
3295 | _ => all) | 3149 | _ => all) |
3296 | _ => all) | 3150 | _ => all) |
3297 | _ => all | 3151 | _ => all |
3298 in | 3152 in |
3299 case hnormCon (env, denv) t of | 3153 case hnormCon env t of |
3300 ((L'.TFun (dom, ran), _), []) => | 3154 (L'.TFun (dom, ran), _) => |
3301 (case hnormCon (env, denv) dom of | 3155 (case hnormCon env dom of |
3302 ((L'.TRecord domR, _), []) => | 3156 (L'.TRecord domR, _) => |
3303 doPage (fn t => (L'.TFun ((L'.TRecord domR, | 3157 doPage (fn t => (L'.TFun ((L'.TRecord domR, |
3304 loc), | 3158 loc), |
3305 t), loc), ran) | 3159 t), loc), ran) |
3306 | _ => all) | 3160 | _ => all) |
3307 | _ => doPage (fn t => t, t) | 3161 | _ => doPage (fn t => t, t) |
3505 NONE => (actual, []) | 3359 NONE => (actual, []) |
3506 | SOME ran => | 3360 | SOME ran => |
3507 let | 3361 let |
3508 val (ran', gs) = elabSgn (env', denv) ran | 3362 val (ran', gs) = elabSgn (env', denv) ran |
3509 in | 3363 in |
3510 subSgn (env', denv) actual ran'; | 3364 subSgn env' actual ran'; |
3511 (ran', gs) | 3365 (ran', gs) |
3512 end | 3366 end |
3513 in | 3367 in |
3514 ((L'.StrFun (m, n, dom', formal, str'), loc), | 3368 ((L'.StrFun (m, n, dom', formal, str'), loc), |
3515 (L'.SgnFun (m, n, dom', formal), loc), | 3369 (L'.SgnFun (m, n, dom', formal), loc), |
3526 val (str2', sgn2, gs2) = elabStr (env, denv) str2 | 3380 val (str2', sgn2, gs2) = elabStr (env, denv) str2 |
3527 in | 3381 in |
3528 case #1 (hnormSgn env sgn1) of | 3382 case #1 (hnormSgn env sgn1) of |
3529 L'.SgnError => (strerror, sgnerror, []) | 3383 L'.SgnError => (strerror, sgnerror, []) |
3530 | L'.SgnFun (m, n, dom, ran) => | 3384 | L'.SgnFun (m, n, dom, ran) => |
3531 (subSgn (env, denv) sgn2 dom; | 3385 (subSgn env sgn2 dom; |
3532 case #1 (hnormSgn env ran) of | 3386 case #1 (hnormSgn env ran) of |
3533 L'.SgnError => (strerror, sgnerror, []) | 3387 L'.SgnError => (strerror, sgnerror, []) |
3534 | L'.SgnConst sgis => | 3388 | L'.SgnConst sgis => |
3535 ((L'.StrApp (str1', str2'), loc), | 3389 ((L'.StrApp (str1', str2'), loc), |
3536 (L'.SgnConst ((L'.SgiStr (m, n, selfifyAt env {str = str2', sgn = sgn2}), loc) :: sgis), loc), | 3390 (L'.SgnConst ((L'.SgiStr (m, n, selfifyAt env {str = str2', sgn = sgn2}), loc) :: sgis), loc), |
3552 raise Fail "Unresolved disjointness constraints in Basis") | 3406 raise Fail "Unresolved disjointness constraints in Basis") |
3553 | 3407 |
3554 val (env', basis_n) = E.pushStrNamed env "Basis" sgn | 3408 val (env', basis_n) = E.pushStrNamed env "Basis" sgn |
3555 val () = basis_r := basis_n | 3409 val () = basis_r := basis_n |
3556 | 3410 |
3557 val (ds, (env', _)) = dopen (env', D.empty) {str = basis_n, strs = [], sgn = sgn} | 3411 val (ds, env') = dopen env' {str = basis_n, strs = [], sgn = sgn} |
3558 | 3412 |
3559 fun discoverC r x = | 3413 fun discoverC r x = |
3560 case E.lookupC env' x of | 3414 case E.lookupC env' x of |
3561 E.NotBound => raise Fail ("Constructor " ^ x ^ " unbound in Basis") | 3415 E.NotBound => raise Fail ("Constructor " ^ x ^ " unbound in Basis") |
3562 | E.Rel _ => raise Fail ("Constructor " ^ x ^ " bound relatively in Basis") | 3416 | E.Rel _ => raise Fail ("Constructor " ^ x ^ " bound relatively in Basis") |
3590 case E.resolveClass env c of | 3444 case E.resolveClass env c of |
3591 SOME e => r := SOME e | 3445 SOME e => r := SOME e |
3592 | NONE => expError env (Unresolvable (loc, c)) | 3446 | NONE => expError env (Unresolvable (loc, c)) |
3593 end) gs | 3447 end) gs |
3594 | 3448 |
3595 val () = subSgn (env', D.empty) topSgn' topSgn | 3449 val () = subSgn env' topSgn' topSgn |
3596 | 3450 |
3597 val (env', top_n) = E.pushStrNamed env' "Top" topSgn | 3451 val (env', top_n) = E.pushStrNamed env' "Top" topSgn |
3598 | 3452 |
3599 val (ds', (env', _)) = dopen (env', D.empty) {str = top_n, strs = [], sgn = topSgn} | 3453 val (ds', env') = dopen env' {str = top_n, strs = [], sgn = topSgn} |
3600 | 3454 |
3601 fun elabDecl' (d, (env, gs)) = | 3455 fun elabDecl' (d, (env, gs)) = |
3602 let | 3456 let |
3603 val () = resetKunif () | 3457 val () = resetKunif () |
3604 val () = resetCunif () | 3458 val () = resetCunif () |