comparison src/elaborate.sml @ 777:87a7702d681d

outer demo
author Adam Chlipala <adamc@hcoop.net>
date Sun, 03 May 2009 14:57:33 -0400
parents 8688e01ae469
children d20d6afc1206
comparison
equal deleted inserted replaced
776:9f2555f06901 777:87a7702d681d
495 fields : (L'.con * L'.con) list, 495 fields : (L'.con * L'.con) list,
496 unifs : (L'.con * L'.con option ref) list, 496 unifs : (L'.con * L'.con option ref) list,
497 others : L'.con list 497 others : L'.con list
498 } 498 }
499 499
500 fun normalizeRecordSummary env (r : record_summary) =
501 let
502 val (fields, unifs, others) =
503 foldl (fn (u as (uc, _), (fields, unifs, others)) =>
504 let
505 val uc' = hnormCon env uc
506 in
507 case #1 uc' of
508 L'.CUnif _ => (fields, u :: unifs, others)
509 | L'.CRecord (_, fs) => (fs @ fields, unifs, others)
510 | L'.CConcat ((L'.CRecord (_, fs), _), rest) => (fs @ fields, unifs, rest :: others)
511 | _ => (fields, unifs, uc' :: others)
512 end)
513 (#fields r, [], #others r) (#unifs r)
514 in
515 {fields = fields, unifs = unifs, others = others}
516 end
517
518 fun summaryToCon {fields, unifs, others} = 500 fun summaryToCon {fields, unifs, others} =
519 let 501 let
520 val c = (L'.CRecord (ktype, []), dummy) 502 val c = (L'.CRecord (ktype, []), dummy)
521 val c = List.foldr (fn (c', c) => (L'.CConcat (c', c), dummy)) c others 503 val c = List.foldr (fn (c', c) => (L'.CConcat (c', c), dummy)) c others
522 val c = List.foldr (fn ((c', _), c) => (L'.CConcat (c', c), dummy)) c unifs 504 val c = List.foldr (fn ((c', _), c) => (L'.CConcat (c', c), dummy)) c unifs
637 | L'.TKFun _ => false 619 | L'.TKFun _ => false
638 620
639 val recdCounter = ref 0 621 val recdCounter = ref 0
640 622
641 val mayDelay = ref false 623 val mayDelay = ref false
642 val delayedUnifs = ref ([] : (E.env * L'.kind * record_summary * record_summary) list) 624 val delayedUnifs = ref ([] : (ErrorMsg.span * E.env * L'.kind * record_summary * record_summary) list)
643 625
644 fun unifyRecordCons env (c1, c2) = 626 fun unifyRecordCons env (loc, c1, c2) =
645 let 627 let
646 fun rkindof c = 628 fun rkindof c =
647 case hnormKind (kindof env c) of 629 case hnormKind (kindof env c) of
648 (L'.KRecord k, _) => k 630 (L'.KRecord k, _) => k
649 | (L'.KError, _) => kerror 631 | (L'.KError, _) => kerror
661 643
662 val r1 = recordSummary env c1 644 val r1 = recordSummary env c1
663 val r2 = recordSummary env c2 645 val r2 = recordSummary env c2
664 in 646 in
665 unifyKinds env k1 k2; 647 unifyKinds env k1 k2;
666 unifySummaries env (k1, r1, r2) 648 unifySummaries env (loc, k1, r1, r2)
667 end 649 end
650
651 and normalizeRecordSummary env (r : record_summary) =
652 recordSummary env (summaryToCon r)
668 653
669 and recordSummary env c = 654 and recordSummary env c =
670 let 655 let
671 val c = hnormCon env c 656 val c = hnormCon env c
672 657
688 in 673 in
689 sum 674 sum
690 end 675 end
691 676
692 and consEq env (c1, c2) = 677 and consEq env (c1, c2) =
693 (unifyCons env c1 c2; 678 let
694 true) 679 val mayDelay' = !mayDelay
695 handle CUnify _ => false 680 in
681 (mayDelay := false;
682 unifyCons env c1 c2;
683 mayDelay := mayDelay';
684 true)
685 handle CUnify _ => (mayDelay := mayDelay'; false)
686 end
696 687
697 and consNeq env (c1, c2) = 688 and consNeq env (c1, c2) =
698 case (#1 (hnormCon env c1), #1 (hnormCon env c2)) of 689 case (#1 (hnormCon env c1), #1 (hnormCon env c2)) of
699 (L'.CName x1, L'.CName x2) => x1 <> x2 690 (L'.CName x1, L'.CName x2) => x1 <> x2
700 | _ => false 691 | _ => false
701 692
702 and unifySummaries env (k, s1 : record_summary, s2 : record_summary) = 693 and unifySummaries env (loc, k, s1 : record_summary, s2 : record_summary) =
703 let 694 let
704 val loc = #2 k 695 val loc = #2 k
696 val pdescs = [("#1", p_summary env s1),
697 ("#2", p_summary env s2)]
705 (*val () = eprefaces "Summaries" [("#1", p_summary env s1), 698 (*val () = eprefaces "Summaries" [("#1", p_summary env s1),
706 ("#2", p_summary env s2)]*) 699 ("#2", p_summary env s2)]*)
707 700
708 fun eatMatching p (ls1, ls2) = 701 fun eatMatching p (ls1, ls2) =
709 let 702 let
789 else 782 else
790 orig 783 orig
791 | orig => orig 784 | orig => orig
792 785
793 (*val () = eprefaces "Summaries4" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}), 786 (*val () = eprefaces "Summaries4" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}),
794 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*) 787 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*)
795 788
796 fun isGuessable (other, fs, unifs) = 789 fun isGuessable (other, fs, unifs) =
797 let 790 let
798 val c = (L'.CRecord (k, fs), loc) 791 val c = (L'.CRecord (k, fs), loc)
799 val c = foldl (fn ((c', _), c) => (L'.CConcat (c', c), loc)) c unifs 792 val c = foldl (fn ((c', _), c) => (L'.CConcat (c', c), loc)) c unifs
809 if isGuessable (other1, fs2, unifs2) then 802 if isGuessable (other1, fs2, unifs2) then
810 ([], [], [], [], [], []) 803 ([], [], [], [], [], [])
811 else 804 else
812 (fs1, fs2, others1, others2, unifs1, unifs2) 805 (fs1, fs2, others1, others2, unifs1, unifs2)
813 | (_, [], [], [other2], _, []) => 806 | (_, [], [], [other2], _, []) =>
814 if isGuessable (other2, fs1, unifs1) then 807 if isGuessable (other2, fs1, unifs1) then
815 ([], [], [], [], [], []) 808 ([], [], [], [], [], [])
816 else 809 else
817 (prefaces "Not guessable" [("other2", p_con env other2), 810 (fs1, fs2, others1, others2, unifs1, unifs2)
818 ("fs1", p_con env (L'.CRecord (k, fs1), loc)),
819 ("#unifs1", PD.string (Int.toString (length unifs1)))];
820 (fs1, fs2, others1, others2, unifs1, unifs2))
821 | _ => (fs1, fs2, others1, others2, unifs1, unifs2) 811 | _ => (fs1, fs2, others1, others2, unifs1, unifs2)
822 812
823 (*val () = eprefaces "Summaries5" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}), 813 (*val () = eprefaces "Summaries5" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}),
824 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*) 814 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*)
825 815
826 val empty = (L'.CRecord (k, []), dummy) 816 val empty = (L'.CRecord (k, []), dummy)
827 fun failure () = raise CUnify' (CRecordFailure (unsummarize s1, unsummarize s2)) 817 fun failure () = raise CUnify' (CRecordFailure (unsummarize s1, unsummarize s2))
828 in 818 in
829 case (unifs1, fs1, others1, unifs2, fs2, others2) of 819 (case (unifs1, fs1, others1, unifs2, fs2, others2) of
830 (_, [], [], [], [], []) => 820 (_, [], [], [], [], []) =>
831 app (fn (_, r) => r := SOME empty) unifs1 821 app (fn (_, r) => r := SOME empty) unifs1
832 | ([], [], [], _, [], []) => 822 | ([], [], [], _, [], []) =>
833 app (fn (_, r) => r := SOME empty) unifs2 823 app (fn (_, r) => r := SOME empty) unifs2
834 | ([], _, _, _, _ :: _, _) => failure () 824 | _ =>
835 | ([], _, _, _, _, _ :: _) => failure () 825 if !mayDelay then
836 | (_, _ :: _, _, [], _, _) => failure () 826 delayedUnifs := (loc, env, k, s1, s2) :: !delayedUnifs
837 | (_, _, _ :: _, [], _, _) => failure () 827 else
838 | _ => 828 failure ())
839 if !mayDelay then 829
840 delayedUnifs := (env, k, s1, s2) :: !delayedUnifs 830 (*before eprefaces "Summaries'" [("#1", p_summary env (normalizeRecordSummary env s1)),
841 else 831 ("#2", p_summary env (normalizeRecordSummary env s2))]*)
842 failure ()
843
844 (*before eprefaces "Summaries'" [("#1", p_summary env s1),
845 ("#2", p_summary env s2)]*)
846 end 832 end
847 833
848 and guessMap env (c1, c2, ex) = 834 and guessMap env (c1, c2, ex) =
849 let 835 let
850 val loc = #2 c1 836 val loc = #2 c1
880 unfold (r1, c1'); 866 unfold (r1, c1');
881 unfold (r2, c2'); 867 unfold (r2, c2');
882 unifyCons env r (L'.CConcat (r1, r2), loc) 868 unifyCons env r (L'.CConcat (r1, r2), loc)
883 end 869 end
884 | L'.CUnif (_, _, _, ur) => 870 | L'.CUnif (_, _, _, ur) =>
885 let 871 ur := SOME (L'.CApp ((L'.CApp ((L'.CMap (dom, ran), loc), f), loc), r), loc)
886 val ur' = cunif (loc, (L'.KRecord dom, loc))
887 in
888 ur := SOME (L'.CApp ((L'.CApp ((L'.CMap (dom, ran), loc), f), loc), ur'), loc)
889 end
890 | _ => raise ex 872 | _ => raise ex
891 in 873 in
892 unfold (r, c) 874 unfold (r, c)
893 end 875 end
894 handle _ => raise ex 876 handle _ => raise ex
976 unifyCons' env c1All (List.nth (us, n2 - 1)) 958 unifyCons' env c1All (List.nth (us, n2 - 1))
977 end 959 end
978 | _ => onFail ()) 960 | _ => onFail ())
979 | _ => onFail () 961 | _ => onFail ()
980 962
981 fun isRecord' () = unifyRecordCons env (c1All, c2All) 963 fun isRecord' () = unifyRecordCons env (loc, c1All, c2All)
982 964
983 fun isRecord () = 965 fun isRecord () =
984 case (c1, c2) of 966 case (c1, c2) of
985 (L'.CProj (c1, n1), _) => projSpecial1 (c1, n1, isRecord') 967 (L'.CProj (c1, n1), _) => projSpecial1 (c1, n1, isRecord')
986 | (_, L'.CProj (c2, n2)) => projSpecial2 (c2, n2, isRecord') 968 | (_, L'.CProj (c2, n2)) => projSpecial2 (c2, n2, isRecord')
3735 (ds, (env, gs)) 3717 (ds, (env, gs))
3736 end 3718 end
3737 3719
3738 val (file, (_, gs)) = ListUtil.foldlMapConcat elabDecl' (env', []) file 3720 val (file, (_, gs)) = ListUtil.foldlMapConcat elabDecl' (env', []) file
3739 3721
3740 val delayed = !delayedUnifs 3722 fun oneSummaryRound () =
3723 if ErrorMsg.anyErrors () then
3724 ()
3725 else
3726 let
3727 val delayed = !delayedUnifs
3728 in
3729 delayedUnifs := [];
3730 app (fn (loc, env, k, s1, s2) =>
3731 unifySummaries env (loc, k, normalizeRecordSummary env s1, normalizeRecordSummary env s2))
3732 delayed
3733 end
3741 in 3734 in
3742 delayedUnifs := []; 3735 oneSummaryRound ();
3743 app (fn (env, k, s1, s2) =>
3744 unifySummaries env (k, normalizeRecordSummary env s1, normalizeRecordSummary env s2))
3745 delayed;
3746 3736
3747 if ErrorMsg.anyErrors () then 3737 if ErrorMsg.anyErrors () then
3748 () 3738 ()
3749 else 3739 else
3750 let 3740 let
3806 end) 3796 end)
3807 false gs 3797 false gs
3808 in 3798 in
3809 case (gs, solved) of 3799 case (gs, solved) of
3810 ([], _) => () 3800 ([], _) => ()
3811 | (_, true) => solver gs 3801 | (_, true) => (oneSummaryRound (); solver gs)
3812 | _ => 3802 | _ =>
3813 app (fn Disjoint (loc, env, denv, c1, c2) => 3803 app (fn Disjoint (loc, env, denv, c1, c2) =>
3814 ((ErrorMsg.errorAt loc "Couldn't prove field name disjointness"; 3804 ((ErrorMsg.errorAt loc "Couldn't prove field name disjointness";
3815 eprefaces' [("Con 1", p_con env c1), 3805 eprefaces' [("Con 1", p_con env c1),
3816 ("Con 2", p_con env c2), 3806 ("Con 2", p_con env c2),
3824 solver gs 3814 solver gs
3825 end; 3815 end;
3826 3816
3827 mayDelay := false; 3817 mayDelay := false;
3828 3818
3829 app (fn (env, k, s1, s2) => 3819 if ErrorMsg.anyErrors () then
3830 unifySummaries env (k, normalizeRecordSummary env s1, normalizeRecordSummary env s2) 3820 ()
3831 handle CUnify' err => (ErrorMsg.errorAt (#2 k) "Error in final record unification"; 3821 else
3832 cunifyError env err)) 3822 (app (fn (loc, env, k, s1, s2) =>
3833 (!delayedUnifs); 3823 unifySummaries env (loc, k, normalizeRecordSummary env s1, normalizeRecordSummary env s2)
3834 delayedUnifs := []; 3824 handle CUnify' err => (ErrorMsg.errorAt loc "Error in final record unification";
3825 cunifyError env err))
3826 (!delayedUnifs);
3827 delayedUnifs := []);
3835 3828
3836 if ErrorMsg.anyErrors () then 3829 if ErrorMsg.anyErrors () then
3837 () 3830 ()
3838 else 3831 else
3839 app (fn f => f ()) (!checks); 3832 app (fn f => f ()) (!checks);