comparison src/elaborate.sml @ 86:7f9bcc8bfa1e

More with disjointness assumptions
author Adam Chlipala <adamc@hcoop.net>
date Tue, 01 Jul 2008 13:19:14 -0400
parents 1f85890c9846
children 7bab29834cd6
comparison
equal deleted inserted replaced
85:1f85890c9846 86:7f9bcc8bfa1e
543 | L'.CUnit => (L'.KUnit, loc) 543 | L'.CUnit => (L'.KUnit, loc)
544 544
545 | L'.CError => kerror 545 | L'.CError => kerror
546 | L'.CUnif (_, k, _, _) => k 546 | L'.CUnif (_, k, _, _) => k
547 547
548 fun unifyRecordCons env (c1, c2) = 548 fun hnormCon (env, denv) c =
549 let
550 val cAll as (c, loc) = ElabOps.hnormCon env c
551
552 fun doDisj (c1, c2, c) =
553 let
554 val (c, gs) = hnormCon (env, denv) c
555 in
556 (c,
557 map (fn cs => (loc, env, denv, cs)) (D.prove env denv (c1, c2, loc)) @ gs)
558 end
559 in
560 case c of
561 L'.CDisjoint cs => doDisj cs
562 | L'.TDisjoint cs => doDisj cs
563 | _ => (cAll, [])
564 end
565
566 fun unifyRecordCons (env, denv) (c1, c2) =
549 let 567 let
550 val k1 = kindof env c1 568 val k1 = kindof env c1
551 val k2 = kindof env c2 569 val k2 = kindof env c2
570
571 val (r1, gs1) = recordSummary (env, denv) c1
572 val (r2, gs2) = recordSummary (env, denv) c2
552 in 573 in
553 unifyKinds k1 k2; 574 unifyKinds k1 k2;
554 unifySummaries env (k1, recordSummary env c1, recordSummary env c2) 575 unifySummaries (env, denv) (k1, r1, r2);
576 gs1 @ gs2
555 end 577 end
556 578
557 and recordSummary env c : record_summary = 579 and recordSummary (env, denv) c =
558 case hnormCon env c of 580 let
559 (L'.CRecord (_, xcs), _) => {fields = xcs, unifs = [], others = []} 581 val (c, gs) = hnormCon (env, denv) c
560 | (L'.CConcat (c1, c2), _) => 582
561 let 583 val (sum, gs') =
562 val s1 = recordSummary env c1 584 case c of
563 val s2 = recordSummary env c2 585 (L'.CRecord (_, xcs), _) => ({fields = xcs, unifs = [], others = []}, [])
564 in 586 | (L'.CConcat (c1, c2), _) =>
565 {fields = #fields s1 @ #fields s2, 587 let
566 unifs = #unifs s1 @ #unifs s2, 588 val (s1, gs1) = recordSummary (env, denv) c1
567 others = #others s1 @ #others s2} 589 val (s2, gs2) = recordSummary (env, denv) c2
568 end 590 in
569 | (L'.CUnif (_, _, _, ref (SOME c)), _) => recordSummary env c 591 ({fields = #fields s1 @ #fields s2,
570 | c' as (L'.CUnif (_, _, _, r), _) => {fields = [], unifs = [(c', r)], others = []} 592 unifs = #unifs s1 @ #unifs s2,
571 | c' => {fields = [], unifs = [], others = [c']} 593 others = #others s1 @ #others s2},
572 594 gs1 @ gs2)
573 and consEq env (c1, c2) = 595 end
574 (unifyCons env c1 c2; 596 | (L'.CUnif (_, _, _, ref (SOME c)), _) => recordSummary (env, denv) c
575 true) 597 | c' as (L'.CUnif (_, _, _, r), _) => ({fields = [], unifs = [(c', r)], others = []}, [])
598 | c' => ({fields = [], unifs = [], others = [c']}, [])
599 in
600 (sum, gs @ gs')
601 end
602
603 and consEq (env, denv) (c1, c2) =
604 (case unifyCons (env, denv) c1 c2 of
605 [] => true
606 | _ => false)
576 handle CUnify _ => false 607 handle CUnify _ => false
577 608
578 and consNeq env (c1, c2) = 609 and consNeq env (c1, c2) =
579 case (#1 (hnormCon env c1), #1 (hnormCon env c2)) of 610 case (#1 (ElabOps.hnormCon env c1), #1 (ElabOps.hnormCon env c2)) of
580 (L'.CName x1, L'.CName x2) => x1 <> x2 611 (L'.CName x1, L'.CName x2) => x1 <> x2
581 | _ => false 612 | _ => false
582 613
583 and unifySummaries env (k, s1 : record_summary, s2 : record_summary) = 614 and unifySummaries (env, denv) (k, s1 : record_summary, s2 : record_summary) =
584 let 615 let
585 (*val () = eprefaces "Summaries" [("#1", p_summary env s1), 616 (*val () = eprefaces "Summaries" [("#1", p_summary env s1),
586 ("#2", p_summary env s2)]*) 617 ("#2", p_summary env s2)]*)
587 618
588 fun eatMatching p (ls1, ls2) = 619 fun eatMatching p (ls1, ls2) =
607 em (ls1, ls2, []) 638 em (ls1, ls2, [])
608 end 639 end
609 640
610 val (fs1, fs2) = eatMatching (fn ((x1, c1), (x2, c2)) => 641 val (fs1, fs2) = eatMatching (fn ((x1, c1), (x2, c2)) =>
611 not (consNeq env (x1, x2)) 642 not (consNeq env (x1, x2))
612 andalso consEq env (c1, c2) 643 andalso consEq (env, denv) (c1, c2)
613 andalso consEq env (x1, x2)) 644 andalso consEq (env, denv) (x1, x2))
614 (#fields s1, #fields s2) 645 (#fields s1, #fields s2)
615 (*val () = eprefaces "Summaries2" [("#1", p_summary env {fields = fs1, unifs = #unifs s1, others = #others s1}), 646 (*val () = eprefaces "Summaries2" [("#1", p_summary env {fields = fs1, unifs = #unifs s1, others = #others s1}),
616 ("#2", p_summary env {fields = fs2, unifs = #unifs s2, others = #others s2})]*) 647 ("#2", p_summary env {fields = fs2, unifs = #unifs s2, others = #others s2})]*)
617 val (unifs1, unifs2) = eatMatching (fn ((_, r1), (_, r2)) => r1 = r2) (#unifs s1, #unifs s2) 648 val (unifs1, unifs2) = eatMatching (fn ((_, r1), (_, r2)) => r1 = r2) (#unifs s1, #unifs s2)
618 val (others1, others2) = eatMatching (consEq env) (#others s1, #others s2) 649 val (others1, others2) = eatMatching (consEq (env, denv)) (#others s1, #others s2)
619 650
620 fun unifFields (fs, others, unifs) = 651 fun unifFields (fs, others, unifs) =
621 case (fs, others, unifs) of 652 case (fs, others, unifs) of
622 ([], [], _) => ([], [], unifs) 653 ([], [], _) => ([], [], unifs)
623 | (_, _, []) => (fs, others, []) 654 | (_, _, []) => (fs, others, [])
643 end 674 end
644 675
645 val (fs1, others1, unifs2) = unifFields (fs1, others1, unifs2) 676 val (fs1, others1, unifs2) = unifFields (fs1, others1, unifs2)
646 val (fs2, others2, unifs1) = unifFields (fs2, others2, unifs1) 677 val (fs2, others2, unifs1) = unifFields (fs2, others2, unifs1)
647 678
648 val clear1 = case (fs1, others1) of 679 val clear = case (fs1, others1, fs2, others2) of
649 ([], []) => true 680 ([], [], [], []) => true
650 | _ => false
651 val clear2 = case (fs2, others2) of
652 ([], []) => true
653 | _ => false 681 | _ => false
654 val empty = (L'.CRecord (k, []), dummy) 682 val empty = (L'.CRecord (k, []), dummy)
655 fun pairOffUnifs (unifs1, unifs2) = 683 fun pairOffUnifs (unifs1, unifs2) =
656 case (unifs1, unifs2) of 684 case (unifs1, unifs2) of
657 ([], _) => 685 ([], _) =>
658 if clear1 then 686 if clear then
659 List.app (fn (_, r) => r := SOME empty) unifs2 687 List.app (fn (_, r) => r := SOME empty) unifs2
660 else 688 else
661 raise CUnify' CRecordFailure 689 raise CUnify' CRecordFailure
662 | (_, []) => 690 | (_, []) =>
663 if clear2 then 691 if clear then
664 List.app (fn (_, r) => r := SOME empty) unifs1 692 List.app (fn (_, r) => r := SOME empty) unifs1
665 else 693 else
666 raise CUnify' CRecordFailure 694 raise CUnify' CRecordFailure
667 | ((c1, _) :: rest1, (_, r2) :: rest2) => 695 | ((c1, _) :: rest1, (_, r2) :: rest2) =>
668 (r2 := SOME c1; 696 (r2 := SOME c1;
669 pairOffUnifs (rest1, rest2)) 697 pairOffUnifs (rest1, rest2))
670 in 698 in
671 pairOffUnifs (unifs1, unifs2) 699 pairOffUnifs (unifs1, unifs2)
672 end 700 end
673 701
674 702 and unifyCons' (env, denv) c1 c2 =
675 and unifyCons' env c1 c2 = 703 let
676 unifyCons'' env (hnormCon env c1) (hnormCon env c2) 704 val (c1, gs1) = hnormCon (env, denv) c1
705 val (c2, gs2) = hnormCon (env, denv) c2
706 in
707 unifyCons'' (env, denv) c1 c2;
708 gs1 @ gs2
709 end
677 710
678 and unifyCons'' env (c1All as (c1, _)) (c2All as (c2, _)) = 711 and unifyCons'' (env, denv) (c1All as (c1, _)) (c2All as (c2, _)) =
679 let 712 let
680 fun err f = raise CUnify' (f (c1All, c2All)) 713 fun err f = raise CUnify' (f (c1All, c2All))
681 714
682 fun isRecord () = unifyRecordCons env (c1All, c2All) 715 fun isRecord () = unifyRecordCons (env, denv) (c1All, c2All)
683 in 716 in
684 case (c1, c2) of 717 case (c1, c2) of
685 (L'.TFun (d1, r1), L'.TFun (d2, r2)) => 718 (L'.TFun (d1, r1), L'.TFun (d2, r2)) =>
686 (unifyCons' env d1 d2; 719 unifyCons' (env, denv) d1 d2
687 unifyCons' env r1 r2) 720 @ unifyCons' (env, denv) r1 r2
688 | (L'.TCFun (expl1, x1, d1, r1), L'.TCFun (expl2, _, d2, r2)) => 721 | (L'.TCFun (expl1, x1, d1, r1), L'.TCFun (expl2, _, d2, r2)) =>
689 if expl1 <> expl2 then 722 if expl1 <> expl2 then
690 err CExplicitness 723 err CExplicitness
691 else 724 else
692 (unifyKinds d1 d2; 725 (unifyKinds d1 d2;
693 unifyCons' (E.pushCRel env x1 d1) r1 r2) 726 unifyCons' (E.pushCRel env x1 d1, D.enter denv) r1 r2)
694 | (L'.TRecord r1, L'.TRecord r2) => unifyCons' env r1 r2 727 | (L'.TRecord r1, L'.TRecord r2) => unifyCons' (env, denv) r1 r2
695 728
696 | (L'.CRel n1, L'.CRel n2) => 729 | (L'.CRel n1, L'.CRel n2) =>
697 if n1 = n2 then 730 if n1 = n2 then
698 () 731 []
699 else 732 else
700 err CIncompatible 733 err CIncompatible
701 | (L'.CNamed n1, L'.CNamed n2) => 734 | (L'.CNamed n1, L'.CNamed n2) =>
702 if n1 = n2 then 735 if n1 = n2 then
703 () 736 []
704 else 737 else
705 err CIncompatible 738 err CIncompatible
706 739
707 | (L'.CApp (d1, r1), L'.CApp (d2, r2)) => 740 | (L'.CApp (d1, r1), L'.CApp (d2, r2)) =>
708 (unifyCons' env d1 d2; 741 (unifyCons' (env, denv) d1 d2;
709 unifyCons' env r1 r2) 742 unifyCons' (env, denv) r1 r2)
710 | (L'.CAbs (x1, k1, c1), L'.CAbs (_, k2, c2)) => 743 | (L'.CAbs (x1, k1, c1), L'.CAbs (_, k2, c2)) =>
711 (unifyKinds k1 k2; 744 (unifyKinds k1 k2;
712 unifyCons' (E.pushCRel env x1 k1) c1 c2) 745 unifyCons' (E.pushCRel env x1 k1, D.enter denv) c1 c2)
713 746
714 | (L'.CName n1, L'.CName n2) => 747 | (L'.CName n1, L'.CName n2) =>
715 if n1 = n2 then 748 if n1 = n2 then
716 () 749 []
717 else 750 else
718 err CIncompatible 751 err CIncompatible
719 752
720 | (L'.CModProj (n1, ms1, x1), L'.CModProj (n2, ms2, x2)) => 753 | (L'.CModProj (n1, ms1, x1), L'.CModProj (n2, ms2, x2)) =>
721 if n1 = n2 andalso ms1 = ms2 andalso x1 = x2 then 754 if n1 = n2 andalso ms1 = ms2 andalso x1 = x2 then
722 () 755 []
723 else 756 else
724 err CIncompatible 757 err CIncompatible
725 758
726 | (L'.CError, _) => () 759 | (L'.CError, _) => []
727 | (_, L'.CError) => () 760 | (_, L'.CError) => []
728 761
729 | (L'.CUnif (_, _, _, ref (SOME c1All)), _) => unifyCons' env c1All c2All 762 | (L'.CUnif (_, _, _, ref (SOME c1All)), _) => unifyCons' (env, denv) c1All c2All
730 | (_, L'.CUnif (_, _, _, ref (SOME c2All))) => unifyCons' env c1All c2All 763 | (_, L'.CUnif (_, _, _, ref (SOME c2All))) => unifyCons' (env, denv) c1All c2All
731 764
732 | (L'.CUnif (_, k1, _, r1), L'.CUnif (_, k2, _, r2)) => 765 | (L'.CUnif (_, k1, _, r1), L'.CUnif (_, k2, _, r2)) =>
733 if r1 = r2 then 766 if r1 = r2 then
734 () 767 []
735 else 768 else
736 (unifyKinds k1 k2; 769 (unifyKinds k1 k2;
737 r1 := SOME c2All) 770 r1 := SOME c2All;
771 [])
738 772
739 | (L'.CUnif (_, _, _, r), _) => 773 | (L'.CUnif (_, _, _, r), _) =>
740 if occursCon r c2All then 774 if occursCon r c2All then
741 err COccursCheckFailed 775 err COccursCheckFailed
742 else 776 else
743 r := SOME c2All 777 (r := SOME c2All;
778 [])
744 | (_, L'.CUnif (_, _, _, r)) => 779 | (_, L'.CUnif (_, _, _, r)) =>
745 if occursCon r c1All then 780 if occursCon r c1All then
746 err COccursCheckFailed 781 err COccursCheckFailed
747 else 782 else
748 r := SOME c1All 783 (r := SOME c1All;
784 [])
749 785
750 | (L'.CRecord _, _) => isRecord () 786 | (L'.CRecord _, _) => isRecord ()
751 | (_, L'.CRecord _) => isRecord () 787 | (_, L'.CRecord _) => isRecord ()
752 | (L'.CConcat _, _) => isRecord () 788 | (L'.CConcat _, _) => isRecord ()
753 | (_, L'.CConcat _) => isRecord () 789 | (_, L'.CConcat _) => isRecord ()
754 790
755 | (L'.CFold (dom1, ran1), L'.CFold (dom2, ran2)) => 791 | (L'.CFold (dom1, ran1), L'.CFold (dom2, ran2)) =>
756 (unifyKinds dom1 dom2; 792 (unifyKinds dom1 dom2;
757 unifyKinds ran1 ran2) 793 unifyKinds ran1 ran2;
794 [])
758 795
759 | _ => err CIncompatible 796 | _ => err CIncompatible
760 end 797 end
761 798
762 and unifyCons env c1 c2 = 799 and unifyCons (env, denv) c1 c2 =
763 unifyCons' env c1 c2 800 unifyCons' (env, denv) c1 c2
764 handle CUnify' err => raise CUnify (c1, c2, err) 801 handle CUnify' err => raise CUnify (c1, c2, err)
765 | KUnify args => raise CUnify (c1, c2, CKind args) 802 | KUnify args => raise CUnify (c1, c2, CKind args)
766 803
767 datatype exp_error = 804 datatype exp_error =
768 UnboundExp of ErrorMsg.span * string 805 UnboundExp of ErrorMsg.span * string
789 | WrongForm (variety, e, t) => 826 | WrongForm (variety, e, t) =>
790 (ErrorMsg.errorAt (#2 e) ("Expression is not a " ^ variety); 827 (ErrorMsg.errorAt (#2 e) ("Expression is not a " ^ variety);
791 eprefaces' [("Expression", p_exp env e), 828 eprefaces' [("Expression", p_exp env e),
792 ("Type", p_con env t)]) 829 ("Type", p_con env t)])
793 830
794 fun checkCon env e c1 c2 = 831 fun checkCon (env, denv) e c1 c2 =
795 unifyCons env c1 c2 832 unifyCons (env, denv) c1 c2
796 handle CUnify (c1, c2, err) => 833 handle CUnify (c1, c2, err) =>
797 expError env (Unify (e, c1, c2, err)) 834 (expError env (Unify (e, c1, c2, err));
835 [])
798 836
799 fun primType env p = 837 fun primType env p =
800 case p of 838 case p of
801 P.Int _ => !int 839 P.Int _ => !int
802 | P.Float _ => !float 840 | P.Float _ => !float
858 | L'.EField (_, _, {field, ...}) => field 896 | L'.EField (_, _, {field, ...}) => field
859 | L'.EFold dom => foldType (dom, loc) 897 | L'.EFold dom => foldType (dom, loc)
860 898
861 | L'.EError => cerror 899 | L'.EError => cerror
862 900
863 fun elabHead env (e as (_, loc)) t = 901 fun elabHead (env, denv) (e as (_, loc)) t =
864 let 902 let
865 fun unravel (t, e) = 903 fun unravel (t, e) =
866 case hnormCon env t of 904 let
867 (L'.TCFun (L'.Implicit, x, k, t'), _) => 905 val (t, gs) = hnormCon (env, denv) t
868 let 906 in
869 val u = cunif (loc, k) 907 case t of
870 in 908 (L'.TCFun (L'.Implicit, x, k, t'), _) =>
871 unravel (subConInCon (0, u) t', 909 let
872 (L'.ECApp (e, u), loc)) 910 val u = cunif (loc, k)
873 end 911
874 | _ => (e, t) 912 val (e, t, gs') = unravel (subConInCon (0, u) t',
913 (L'.ECApp (e, u), loc))
914 in
915 (e, t, gs @ gs')
916 end
917 | _ => (e, t, gs)
918 end
875 in 919 in
876 unravel (t, e) 920 unravel (t, e)
877 end 921 end
878 922
879 fun elabExp (env, denv) (e, loc) = 923 fun elabExp (env, denv) (e, loc) =
880 case e of 924 case e of
881 L.EAnnot (e, t) => 925 L.EAnnot (e, t) =>
882 let 926 let
883 val (e', et, gs1) = elabExp (env, denv) e 927 val (e', et, gs1) = elabExp (env, denv) e
884 val (t', _, gs2) = elabCon (env, denv) t 928 val (t', _, gs2) = elabCon (env, denv) t
885 in 929 val gs3 = checkCon (env, denv) e' et t'
886 checkCon env e' et t'; 930 in
887 (e', t', gs1 @ gs2) 931 (e', t', gs1 @ gs2 @ gs3)
888 end 932 end
889 933
890 | L.EPrim p => ((L'.EPrim p, loc), primType env p, []) 934 | L.EPrim p => ((L'.EPrim p, loc), primType env p, [])
891 | L.EVar ([], s) => 935 | L.EVar ([], s) =>
892 (case E.lookupE env s of 936 (case E.lookupE env s of
917 end) 961 end)
918 962
919 | L.EApp (e1, e2) => 963 | L.EApp (e1, e2) =>
920 let 964 let
921 val (e1', t1, gs1) = elabExp (env, denv) e1 965 val (e1', t1, gs1) = elabExp (env, denv) e1
922 val (e1', t1) = elabHead env e1' t1 966 val (e1', t1, gs2) = elabHead (env, denv) e1' t1
923 val (e2', t2, gs2) = elabExp (env, denv) e2 967 val (e2', t2, gs3) = elabExp (env, denv) e2
924 968
925 val dom = cunif (loc, ktype) 969 val dom = cunif (loc, ktype)
926 val ran = cunif (loc, ktype) 970 val ran = cunif (loc, ktype)
927 val t = (L'.TFun (dom, ran), dummy) 971 val t = (L'.TFun (dom, ran), dummy)
928 in 972
929 checkCon env e1' t1 t; 973 val gs4 = checkCon (env, denv) e1' t1 t
930 checkCon env e2' t2 dom; 974 val gs5 = checkCon (env, denv) e2' t2 dom
931 ((L'.EApp (e1', e2'), loc), ran, gs1 @ gs2) 975 in
976 ((L'.EApp (e1', e2'), loc), ran, gs1 @ gs2 @ gs3 @ gs4 @ gs5)
932 end 977 end
933 | L.EAbs (x, to, e) => 978 | L.EAbs (x, to, e) =>
934 let 979 let
935 val (t', gs1) = case to of 980 val (t', gs1) = case to of
936 NONE => (cunif (loc, ktype), []) 981 NONE => (cunif (loc, ktype), [])
948 gs1 @ gs2) 993 gs1 @ gs2)
949 end 994 end
950 | L.ECApp (e, c) => 995 | L.ECApp (e, c) =>
951 let 996 let
952 val (e', et, gs1) = elabExp (env, denv) e 997 val (e', et, gs1) = elabExp (env, denv) e
953 val (e', et) = elabHead env e' et 998 val (e', et, gs2) = elabHead (env, denv) e' et
954 val (c', ck, gs2) = elabCon (env, denv) c 999 val (c', ck, gs3) = elabCon (env, denv) c
955 in 1000 val ((et', _), gs4) = hnormCon (env, denv) et
956 case #1 (hnormCon env et) of 1001 in
1002 case et' of
957 L'.CError => (eerror, cerror, []) 1003 L'.CError => (eerror, cerror, [])
958 | L'.TCFun (_, _, k, eb) => 1004 | L'.TCFun (_, _, k, eb) =>
959 let 1005 let
960 val () = checkKind env c' ck k 1006 val () = checkKind env c' ck k
961 val eb' = subConInCon (0, c') eb 1007 val eb' = subConInCon (0, c') eb
962 handle SynUnif => (expError env (Unif ("substitution", eb)); 1008 handle SynUnif => (expError env (Unif ("substitution", eb));
963 cerror) 1009 cerror)
964 in 1010 in
965 ((L'.ECApp (e', c'), loc), eb', gs1 @ gs2) 1011 ((L'.ECApp (e', c'), loc), eb', gs1 @ gs2 @ gs3 @ gs4)
966 end 1012 end
967 1013
968 | L'.CUnif _ => 1014 | L'.CUnif _ =>
969 (expError env (Unif ("application", et)); 1015 (expError env (Unif ("application", et));
970 (eerror, cerror, [])) 1016 (eerror, cerror, []))
1010 in 1056 in
1011 checkKind env x' xk kname; 1057 checkKind env x' xk kname;
1012 ((x', e', et), gs1 @ gs2 @ gs) 1058 ((x', e', et), gs1 @ gs2 @ gs)
1013 end) 1059 end)
1014 [] xes 1060 [] xes
1061
1062 val k = (L'.KType, loc)
1063
1064 fun prove (xets, gs) =
1065 case xets of
1066 [] => gs
1067 | (x, _, t) :: rest =>
1068 let
1069 val xc = (x, t)
1070 val r1 = (L'.CRecord (k, [xc]), loc)
1071 val gs = foldl (fn ((x', _, t'), gs) =>
1072 let
1073 val xc' = (x', t')
1074 val r2 = (L'.CRecord (k, [xc']), loc)
1075 in
1076 map (fn cs => (loc, env, denv, cs)) (D.prove env denv (r1, r2, loc))
1077 @ gs
1078 end)
1079 gs rest
1080 in
1081 prove (rest, gs)
1082 end
1015 in 1083 in
1016 ((L'.ERecord xes', loc), 1084 ((L'.ERecord xes', loc),
1017 (L'.TRecord (L'.CRecord (ktype, map (fn (x', _, et) => (x', et)) xes'), loc), loc), 1085 (L'.TRecord (L'.CRecord (ktype, map (fn (x', _, et) => (x', et)) xes'), loc), loc),
1018 gs) 1086 prove (xes', gs))
1019 end 1087 end
1020 1088
1021 | L.EField (e, c) => 1089 | L.EField (e, c) =>
1022 let 1090 let
1023 val (e', et, gs1) = elabExp (env, denv) e 1091 val (e', et, gs1) = elabExp (env, denv) e
1024 val (c', ck, gs2) = elabCon (env, denv) c 1092 val (c', ck, gs2) = elabCon (env, denv) c
1025 1093
1026 val ft = cunif (loc, ktype) 1094 val ft = cunif (loc, ktype)
1027 val rest = cunif (loc, ktype_record) 1095 val rest = cunif (loc, ktype_record)
1028 in 1096 val first = (L'.CRecord (ktype, [(c', ft)]), loc)
1029 checkKind env c' ck kname; 1097
1030 checkCon env e' et (L'.TRecord (L'.CConcat ((L'.CRecord (ktype, [(c', ft)]), loc), rest), loc), loc); 1098 val gs3 =
1031 ((L'.EField (e', c', {field = ft, rest = rest}), loc), ft, gs1 @ gs2) 1099 checkCon (env, denv) e' et
1100 (L'.TRecord (L'.CConcat (first, rest), loc), loc)
1101 val gs4 =
1102 map (fn cs => (loc, env, denv, cs))
1103 (D.prove env denv (first, rest, loc))
1104 in
1105 ((L'.EField (e', c', {field = ft, rest = rest}), loc), ft, gs1 @ gs2 @ gs3 @ gs4)
1032 end 1106 end
1033 1107
1034 | L.EFold => 1108 | L.EFold =>
1035 let 1109 let
1036 val dom = kunif loc 1110 val dom = kunif loc
1371 | L'.DVal (x, n, t, _) => (L'.SgiVal (x, n, t), loc) 1445 | L'.DVal (x, n, t, _) => (L'.SgiVal (x, n, t), loc)
1372 | L'.DSgn (x, n, sgn) => (L'.SgiSgn (x, n, sgn), loc) 1446 | L'.DSgn (x, n, sgn) => (L'.SgiSgn (x, n, sgn), loc)
1373 | L'.DStr (x, n, sgn, _) => (L'.SgiStr (x, n, sgn), loc) 1447 | L'.DStr (x, n, sgn, _) => (L'.SgiStr (x, n, sgn), loc)
1374 | L'.DFfiStr (x, n, sgn) => (L'.SgiStr (x, n, sgn), loc) 1448 | L'.DFfiStr (x, n, sgn) => (L'.SgiStr (x, n, sgn), loc)
1375 1449
1376 fun subSgn env sgn1 (sgn2 as (_, loc2)) = 1450 fun subSgn (env, denv) sgn1 (sgn2 as (_, loc2)) =
1377 case (#1 (hnormSgn env sgn1), #1 (hnormSgn env sgn2)) of 1451 case (#1 (hnormSgn env sgn1), #1 (hnormSgn env sgn2)) of
1378 (L'.SgnError, _) => () 1452 (L'.SgnError, _) => ()
1379 | (_, L'.SgnError) => () 1453 | (_, L'.SgnError) => ()
1380 1454
1381 | (L'.SgnConst sgis1, L'.SgnConst sgis2) => 1455 | (L'.SgnConst sgis1, L'.SgnConst sgis2) =>
1426 seek (fn sgi1All as (sgi1, _) => 1500 seek (fn sgi1All as (sgi1, _) =>
1427 case sgi1 of 1501 case sgi1 of
1428 L'.SgiCon (x', n1, k1, c1) => 1502 L'.SgiCon (x', n1, k1, c1) =>
1429 if x = x' then 1503 if x = x' then
1430 let 1504 let
1431 val () = unifyCons env c1 c2 1505 fun good () = SOME (E.pushCNamedAs env x n2 k2 (SOME c2))
1432 handle CUnify (c1, c2, err) =>
1433 sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err))
1434 in 1506 in
1435 SOME (E.pushCNamedAs env x n2 k2 (SOME c2)) 1507 (case unifyCons (env, denv) c1 c2 of
1508 [] => good ()
1509 | _ => NONE)
1510 handle CUnify (c1, c2, err) =>
1511 (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err));
1512 good ())
1436 end 1513 end
1437 else 1514 else
1438 NONE 1515 NONE
1439 | _ => NONE) 1516 | _ => NONE)
1440 1517
1441 | L'.SgiVal (x, n2, c2) => 1518 | L'.SgiVal (x, n2, c2) =>
1442 seek (fn sgi1All as (sgi1, _) => 1519 seek (fn sgi1All as (sgi1, _) =>
1443 case sgi1 of 1520 case sgi1 of
1444 L'.SgiVal (x', n1, c1) => 1521 L'.SgiVal (x', n1, c1) =>
1445 if x = x' then 1522 if x = x' then
1446 let 1523 (case unifyCons (env, denv) c1 c2 of
1447 val () = unifyCons env c1 c2 1524 [] => SOME env
1448 handle CUnify (c1, c2, err) => 1525 | _ => NONE)
1449 sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)) 1526 handle CUnify (c1, c2, err) =>
1450 in 1527 (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err));
1451 SOME env 1528 SOME env)
1452 end
1453 else 1529 else
1454 NONE 1530 NONE
1455 | _ => NONE) 1531 | _ => NONE)
1456 1532
1457 | L'.SgiStr (x, n2, sgn2) => 1533 | L'.SgiStr (x, n2, sgn2) =>
1458 seek (fn sgi1All as (sgi1, _) => 1534 seek (fn sgi1All as (sgi1, _) =>
1459 case sgi1 of 1535 case sgi1 of
1460 L'.SgiStr (x', n1, sgn1) => 1536 L'.SgiStr (x', n1, sgn1) =>
1461 if x = x' then 1537 if x = x' then
1462 let 1538 let
1463 val () = subSgn env sgn1 sgn2 1539 val () = subSgn (env, denv) sgn1 sgn2
1464 val env = E.pushStrNamedAs env x n1 sgn1 1540 val env = E.pushStrNamedAs env x n1 sgn1
1465 val env = if n1 = n2 then 1541 val env = if n1 = n2 then
1466 env 1542 env
1467 else 1543 else
1468 E.pushStrNamedAs env x n2 1544 E.pushStrNamedAs env x n2
1479 seek (fn sgi1All as (sgi1, _) => 1555 seek (fn sgi1All as (sgi1, _) =>
1480 case sgi1 of 1556 case sgi1 of
1481 L'.SgiSgn (x', n1, sgn1) => 1557 L'.SgiSgn (x', n1, sgn1) =>
1482 if x = x' then 1558 if x = x' then
1483 let 1559 let
1484 val () = subSgn env sgn1 sgn2 1560 val () = subSgn (env, denv) sgn1 sgn2
1485 val () = subSgn env sgn2 sgn1 1561 val () = subSgn (env, denv) sgn2 sgn1
1486 1562
1487 val env = E.pushSgnNamedAs env x n2 sgn2 1563 val env = E.pushSgnNamedAs env x n2 sgn2
1488 val env = if n1 = n2 then 1564 val env = if n1 = n2 then
1489 env 1565 env
1490 else 1566 else
1506 if n1 = n2 then 1582 if n1 = n2 then
1507 ran1 1583 ran1
1508 else 1584 else
1509 subStrInSgn (n1, n2) ran1 1585 subStrInSgn (n1, n2) ran1
1510 in 1586 in
1511 subSgn env dom2 dom1; 1587 subSgn (env, denv) dom2 dom1;
1512 subSgn (E.pushStrNamedAs env m2 n2 dom2) ran1 ran2 1588 subSgn (E.pushStrNamedAs env m2 n2 dom2, denv) ran1 ran2
1513 end 1589 end
1514 1590
1515 | _ => sgnError env (SgnWrongForm (sgn1, sgn2)) 1591 | _ => sgnError env (SgnWrongForm (sgn1, sgn2))
1516 1592
1517 1593
1536 NONE => (cunif (loc, ktype), ktype, []) 1612 NONE => (cunif (loc, ktype), ktype, [])
1537 | SOME c => elabCon (env, denv) c 1613 | SOME c => elabCon (env, denv) c
1538 1614
1539 val (e', et, gs2) = elabExp (env, denv) e 1615 val (e', et, gs2) = elabExp (env, denv) e
1540 val (env', n) = E.pushENamed env x c' 1616 val (env', n) = E.pushENamed env x c'
1541 in 1617
1542 checkCon env e' et c'; 1618 val gs3 = checkCon (env, denv) e' et c'
1543 1619 in
1544 ([(L'.DVal (x, n, c', e'), loc)], (env', gs1 @ gs2 @ gs)) 1620 ([(L'.DVal (x, n, c', e'), loc)], (env', gs1 @ gs2 @ gs3 @ gs))
1545 end 1621 end
1546 1622
1547 | L.DSgn (x, sgn) => 1623 | L.DSgn (x, sgn) =>
1548 let 1624 let
1549 val (sgn', gs') = elabSgn (env, denv) sgn 1625 val (sgn', gs') = elabSgn (env, denv) sgn
1600 | _ => str) 1676 | _ => str)
1601 | _ => str 1677 | _ => str
1602 1678
1603 val (str', actual, gs2) = elabStr (env, denv) str 1679 val (str', actual, gs2) = elabStr (env, denv) str
1604 in 1680 in
1605 subSgn env actual formal; 1681 subSgn (env, denv) actual formal;
1606 (str', formal, gs1 @ gs2) 1682 (str', formal, gs1 @ gs2)
1607 end 1683 end
1608 1684
1609 val (env', n) = E.pushStrNamed env x sgn' 1685 val (env', n) = E.pushStrNamed env x sgn'
1610 in 1686 in
1737 NONE => (actual, []) 1813 NONE => (actual, [])
1738 | SOME ran => 1814 | SOME ran =>
1739 let 1815 let
1740 val (ran', gs) = elabSgn (env', denv) ran 1816 val (ran', gs) = elabSgn (env', denv) ran
1741 in 1817 in
1742 subSgn env' actual ran'; 1818 subSgn (env', denv) actual ran';
1743 (ran', gs) 1819 (ran', gs)
1744 end 1820 end
1745 in 1821 in
1746 ((L'.StrFun (m, n, dom', formal, str'), loc), 1822 ((L'.StrFun (m, n, dom', formal, str'), loc),
1747 (L'.SgnFun (m, n, dom', formal), loc), 1823 (L'.SgnFun (m, n, dom', formal), loc),
1753 val (str2', sgn2, gs2) = elabStr (env, denv) str2 1829 val (str2', sgn2, gs2) = elabStr (env, denv) str2
1754 in 1830 in
1755 case #1 (hnormSgn env sgn1) of 1831 case #1 (hnormSgn env sgn1) of
1756 L'.SgnError => (strerror, sgnerror, []) 1832 L'.SgnError => (strerror, sgnerror, [])
1757 | L'.SgnFun (m, n, dom, ran) => 1833 | L'.SgnFun (m, n, dom, ran) =>
1758 (subSgn env sgn2 dom; 1834 (subSgn (env, denv) sgn2 dom;
1759 case #1 (hnormSgn env ran) of 1835 case #1 (hnormSgn env ran) of
1760 L'.SgnError => (strerror, sgnerror, []) 1836 L'.SgnError => (strerror, sgnerror, [])
1761 | L'.SgnConst sgis => 1837 | L'.SgnConst sgis =>
1762 ((L'.StrApp (str1', str2'), loc), 1838 ((L'.StrApp (str1', str2'), loc),
1763 (L'.SgnConst ((L'.SgiStr (m, n, selfifyAt env {str = str2', sgn = sgn2}), loc) :: sgis), loc), 1839 (L'.SgnConst ((L'.SgiStr (m, n, selfifyAt env {str = str2', sgn = sgn2}), loc) :: sgis), loc),
1818 else 1894 else
1819 app (fn (loc, env, denv, (c1, c2)) => 1895 app (fn (loc, env, denv, (c1, c2)) =>
1820 case D.prove env denv (c1, c2, loc) of 1896 case D.prove env denv (c1, c2, loc) of
1821 [] => () 1897 [] => ()
1822 | _ => 1898 | _ =>
1823 (ErrorMsg.errorAt loc "Remaining constraint"; 1899 (ErrorMsg.errorAt loc "Couldn't prove field name disjointness";
1824 eprefaces' [("Con 1", p_con env c1), 1900 eprefaces' [("Con 1", p_con env c1),
1825 ("Con 2", p_con env c2)])) gs; 1901 ("Con 2", p_con env c2)])) gs;
1826 1902
1827 (L'.DFfiStr ("Basis", basis_n, sgn), ErrorMsg.dummySpan) :: ds @ file 1903 (L'.DFfiStr ("Basis", basis_n, sgn), ErrorMsg.dummySpan) :: ds @ file
1828 end 1904 end