comparison src/elaborate.sml @ 710:71409a4ccb67

Get demo type-inferring again
author Adam Chlipala <adamc@hcoop.net>
date Tue, 07 Apr 2009 20:38:01 -0400
parents 0406e9cccb72
children 7292bcb7c02d
comparison
equal deleted inserted replaced
709:0406e9cccb72 710:71409a4ccb67
461 case k of 461 case k of
462 L'.KUnif (_, _, ref NONE) => true 462 L'.KUnif (_, _, ref NONE) => true
463 | _ => false 463 | _ => false
464 fun cunifsRemain c = 464 fun cunifsRemain c =
465 case c of 465 case c of
466 L'.CUnif (loc, (L'.KRecord k, _), _, r as ref NONE) => 466 L'.CUnif (loc, _, _, ref NONE) => SOME loc
467 (r := SOME (L'.CRecord (k, []), loc);
468 NONE)
469 | L'.CUnif (loc, _, _, ref NONE) => SOME loc
470 | _ => NONE 467 | _ => NONE
471 468
472 val kunifsInDecl = U.Decl.exists {kind = kunifsRemain, 469 val kunifsInDecl = U.Decl.exists {kind = kunifsRemain,
473 con = fn _ => false, 470 con = fn _ => false,
474 exp = fn _ => false, 471 exp = fn _ => false,
725 in 722 in
726 foldl (fn (c1, c2) => (L'.CConcat (c1, c2), loc)) 723 foldl (fn (c1, c2) => (L'.CConcat (c1, c2), loc))
727 c others 724 c others
728 end 725 end
729 726
727 val empties = ([], [], [], [], [], [])
728
730 val (unifs1, fs1, others1, unifs2, fs2, others2) = 729 val (unifs1, fs1, others1, unifs2, fs2, others2) =
731 case (unifs1, fs1, others1, unifs2, fs2, others2) of 730 case (unifs1, fs1, others1, unifs2, fs2, others2) of
732 orig as ([(_, r)], [], [], _, _, _) => 731 orig as ([(_, r)], [], [], _, _, _) =>
733 let 732 let
734 val c = unsummarize {fields = fs2, others = others2, unifs = unifs2} 733 val c = unsummarize {fields = fs2, others = others2, unifs = unifs2}
735 in 734 in
736 if occursCon r c then 735 if occursCon r c then
737 orig 736 orig
738 else 737 else
739 (r := SOME c; 738 (r := SOME c;
740 ([], [], [], [], [], [])) 739 empties)
741 end 740 end
742 | orig as (_, _, _, [(_, r)], [], []) => 741 | orig as (_, _, _, [(_, r)], [], []) =>
743 let 742 let
744 val c = unsummarize {fields = fs1, others = others1, unifs = unifs1} 743 val c = unsummarize {fields = fs1, others = others1, unifs = unifs1}
745 in 744 in
746 if occursCon r c then 745 if occursCon r c then
747 orig 746 orig
748 else 747 else
749 (r := SOME c; 748 (r := SOME c;
750 ([], [], [], [], [], [])) 749 empties)
751 end 750 end
751 | orig as ([(_, r1 as ref NONE)], _, [], [(_, r2 as ref NONE)], _, []) =>
752 if List.all (fn (x1, _) => List.all (fn (x2, _) => consNeq env (x1, x2)) fs2) fs1 then
753 let
754 val kr = (L'.KRecord k, dummy)
755 val u = cunif (loc, kr)
756 in
757 r1 := SOME (L'.CConcat ((L'.CRecord (k, fs2), loc), u), loc);
758 r2 := SOME (L'.CConcat ((L'.CRecord (k, fs1), loc), u), loc);
759 empties
760 end
761 else
762 orig
752 | orig => orig 763 | orig => orig
753 764
754 fun unifFields (fs, others, unifs) =
755 case (fs, others, unifs) of
756 ([], [], _) => ([], [], unifs)
757 | (_, _, []) => (fs, others, [])
758 | (_, _, (_, r) :: rest) =>
759 let
760 val r' = ref NONE
761 val kr = (L'.KRecord k, dummy)
762 val cr' = (L'.CUnif (dummy, kr, ("recd" ^ Int.toString (!recdCounter)), r'), dummy)
763 val () = recdCounter := 1 + !recdCounter
764
765 val prefix = case (fs, others) of
766 ([], other :: others) =>
767 List.foldl (fn (other, c) =>
768 (L'.CConcat (c, other), dummy))
769 other others
770 | (fs, []) =>
771 (L'.CRecord (k, fs), dummy)
772 | (fs, others) =>
773 List.foldl (fn (other, c) =>
774 (L'.CConcat (c, other), dummy))
775 (L'.CRecord (k, fs), dummy) others
776 in
777 r := SOME (L'.CConcat (prefix, cr'), dummy);
778 ([], [], (cr', r') :: rest)
779 end
780
781 val (fs1, others1, unifs2) = unifFields (fs1, others1, unifs2)
782 val (fs2, others2, unifs1) = unifFields (fs2, others2, unifs1)
783
784 (*val () = eprefaces "Summaries4" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}), 765 (*val () = eprefaces "Summaries4" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}),
785 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*) 766 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*)
786 767
787 fun isGuessable (other, fs) = 768 fun isGuessable (other, fs) =
788 (guessMap env (other, (L'.CRecord (k, fs), loc), GuessFailure); 769 (guessMap env (other, (L'.CRecord (k, fs), loc), GuessFailure);
789 true) 770 true)
790 handle GuessFailure => false 771 handle GuessFailure => false
801 ([], [], [], []) 782 ([], [], [], [])
802 else 783 else
803 (fs1, fs2, others1, others2) 784 (fs1, fs2, others1, others2)
804 | _ => (fs1, fs2, others1, others2) 785 | _ => (fs1, fs2, others1, others2)
805 786
806 val (unifs1, unifs2) = eatMatching (fn ((_, r1), (_, r2)) => r1 = r2) (unifs1, unifs2)
807
808 (*val () = eprefaces "Summaries5" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}), 787 (*val () = eprefaces "Summaries5" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}),
809 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*) 788 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*)
810 789
811 val clear = case (fs1, others1, fs2, others2) of 790 val clear = case (fs1, others1, fs2, others2) of
812 ([], [], [], []) => true 791 ([], [], [], []) => true
813 | _ => false 792 | _ => false
814 val empty = (L'.CRecord (k, []), dummy) 793 val empty = (L'.CRecord (k, []), dummy)
815
816 fun failure () = raise CUnify' (CRecordFailure (unsummarize s1, unsummarize s2))
817 in 794 in
818 case (unifs1, fs1, others1, unifs2, fs2, others2) of 795 case (unifs1, fs1, others1, unifs2, fs2, others2) of
819 ([(_, r)], [], [], _, _, _) => 796 (_, [], [], [], [], []) =>
820 let 797 app (fn (_, r) => r := SOME empty) unifs1
821 val c = unsummarize {fields = fs2, others = others2, unifs = unifs2} 798 | ([], [], [], _, [], []) =>
822 in 799 app (fn (_, r) => r := SOME empty) unifs2
823 if occursCon r c then
824 failure ()
825 else
826 r := SOME c
827 end
828 | (_, _, _, [(_, r)], [], []) =>
829 let
830 val c = unsummarize {fields = fs1, others = others1, unifs = unifs1}
831 in
832 if occursCon r c then
833 failure ()
834 else
835 r := SOME c
836 end
837 | _ => if clear then 800 | _ => if clear then
838 () 801 ()
839 else 802 else
840 failure () 803 raise CUnify' (CRecordFailure (unsummarize s1, unsummarize s2))
841 (*before eprefaces "Summaries'" [("#1", p_summary env s1), 804 (*before eprefaces "Summaries'" [("#1", p_summary env s1),
842 ("#2", p_summary env s2)]*) 805 ("#2", p_summary env s2)]*)
843 end 806 end
844 807
845 and guessMap env (c1, c2, ex) = 808 and guessMap env (c1, c2, ex) =