comparison src/elaborate.sml @ 713:baaae037e7f6

Retry failed record summary unifications at the end, in hopes that more has been learned
author Adam Chlipala <adamc@hcoop.net>
date Thu, 09 Apr 2009 14:59:29 -0400
parents 915ec60592d4
children f152f215a02c
comparison
equal deleted inserted replaced
712:915ec60592d4 713:baaae037e7f6
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
500 fun summaryToCon {fields, unifs, others} = 518 fun summaryToCon {fields, unifs, others} =
501 let 519 let
502 val c = (L'.CRecord (ktype, []), dummy) 520 val c = (L'.CRecord (ktype, []), dummy)
503 val c = List.foldr (fn (c', c) => (L'.CConcat (c', c), dummy)) c others 521 val c = List.foldr (fn (c', c) => (L'.CConcat (c', c), dummy)) c others
504 val c = List.foldr (fn ((c', _), c) => (L'.CConcat (c', c), dummy)) c unifs 522 val c = List.foldr (fn ((c', _), c) => (L'.CConcat (c', c), dummy)) c unifs
617 | L'.CKAbs _ => false 635 | L'.CKAbs _ => false
618 | L'.CKApp _ => false 636 | L'.CKApp _ => false
619 | L'.TKFun _ => false 637 | L'.TKFun _ => false
620 638
621 val recdCounter = ref 0 639 val recdCounter = ref 0
640
641 val mayDelay = ref false
642 val delayedUnifs = ref ([] : (E.env * L'.kind * record_summary * record_summary) list)
622 643
623 fun unifyRecordCons env (c1, c2) = 644 fun unifyRecordCons env (c1, c2) =
624 let 645 let
625 fun rkindof c = 646 fun rkindof c =
626 case hnormKind (kindof env c) of 647 case hnormKind (kindof env c) of
785 | _ => (fs1, fs2, others1, others2) 806 | _ => (fs1, fs2, others1, others2)
786 807
787 (*val () = eprefaces "Summaries5" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}), 808 (*val () = eprefaces "Summaries5" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}),
788 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*) 809 ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*)
789 810
790 val clear = case (fs1, others1, fs2, others2) of
791 ([], [], [], []) => true
792 | _ => false
793 val empty = (L'.CRecord (k, []), dummy) 811 val empty = (L'.CRecord (k, []), dummy)
812 fun failure () = raise CUnify' (CRecordFailure (unsummarize s1, unsummarize s2))
794 in 813 in
795 case (unifs1, fs1, others1, unifs2, fs2, others2) of 814 case (unifs1, fs1, others1, unifs2, fs2, others2) of
796 (_, [], [], [], [], []) => 815 (_, [], [], [], [], []) =>
797 app (fn (_, r) => r := SOME empty) unifs1 816 app (fn (_, r) => r := SOME empty) unifs1
798 | ([], [], [], _, [], []) => 817 | ([], [], [], _, [], []) =>
799 app (fn (_, r) => r := SOME empty) unifs2 818 app (fn (_, r) => r := SOME empty) unifs2
800 | _ => if clear then 819 | ([], _, _, _, _ :: _, _) => failure ()
801 () 820 | ([], _, _, _, _, _ :: _) => failure ()
802 else 821 | (_, _ :: _, _, [], _, _) => failure ()
803 raise CUnify' (CRecordFailure (unsummarize s1, unsummarize s2)) 822 | (_, _, _ :: _, [], _, _) => failure ()
823 | _ =>
824 if !mayDelay then
825 delayedUnifs := (env, k, s1, s2) :: !delayedUnifs
826 else
827 failure ()
828
804 (*before eprefaces "Summaries'" [("#1", p_summary env s1), 829 (*before eprefaces "Summaries'" [("#1", p_summary env s1),
805 ("#2", p_summary env s2)]*) 830 ("#2", p_summary env s2)]*)
806 end 831 end
807 832
808 and guessMap env (c1, c2, ex) = 833 and guessMap env (c1, c2, ex) =
3552 (strerror, sgnerror, [])) 3577 (strerror, sgnerror, []))
3553 end 3578 end
3554 3579
3555 fun elabFile basis topStr topSgn env file = 3580 fun elabFile basis topStr topSgn env file =
3556 let 3581 let
3582 val () = mayDelay := true
3583 val () = delayedUnifs := []
3584
3557 val (sgn, gs) = elabSgn (env, D.empty) (L.SgnConst basis, ErrorMsg.dummySpan) 3585 val (sgn, gs) = elabSgn (env, D.empty) (L.SgnConst basis, ErrorMsg.dummySpan)
3558 val () = case gs of 3586 val () = case gs of
3559 [] => () 3587 [] => ()
3560 | _ => (app (fn (_, env, _, c1, c2) => 3588 | _ => (app (fn (_, env, _, c1, c2) =>
3561 prefaces "Unresolved" 3589 prefaces "Unresolved"
3609 val (env', top_n) = E.pushStrNamed env' "Top" topSgn 3637 val (env', top_n) = E.pushStrNamed env' "Top" topSgn
3610 val () = top_r := top_n 3638 val () = top_r := top_n
3611 3639
3612 val (ds', env') = dopen env' {str = top_n, strs = [], sgn = topSgn} 3640 val (ds', env') = dopen env' {str = top_n, strs = [], sgn = topSgn}
3613 3641
3642 val checks = ref ([] : (unit -> unit) list)
3643
3614 fun elabDecl' (d, (env, gs)) = 3644 fun elabDecl' (d, (env, gs)) =
3615 let 3645 let
3616 val () = resetKunif () 3646 val () = resetKunif ()
3617 val () = resetCunif () 3647 val () = resetCunif ()
3618 val (ds, (env, _, gs)) = elabDecl (d, (env, D.empty, gs)) 3648 val (ds, (env, _, gs)) = elabDecl (d, (env, D.empty, gs))
3619 in 3649 in
3620 if ErrorMsg.anyErrors () then 3650 checks :=
3621 () 3651 (fn () =>
3622 else ( 3652 (if List.exists kunifsInDecl ds then
3623 if List.exists kunifsInDecl ds then 3653 declError env (KunifsRemain ds)
3624 declError env (KunifsRemain ds) 3654 else
3625 else 3655 ();
3626 (); 3656
3627 3657 case ListUtil.search cunifsInDecl ds of
3628 case ListUtil.search cunifsInDecl ds of 3658 NONE => ()
3629 NONE => () 3659 | SOME loc =>
3630 | SOME loc => 3660 declError env (CunifsRemain ds)))
3631 declError env (CunifsRemain ds) 3661 :: !checks;
3632 );
3633 3662
3634 (ds, (env, gs)) 3663 (ds, (env, gs))
3635 end 3664 end
3636 3665
3637 val (file, (_, gs)) = ListUtil.foldlMapConcat elabDecl' (env', []) file 3666 val (file, (_, gs)) = ListUtil.foldlMapConcat elabDecl' (env', []) file
3638 in 3667 in
3668 mayDelay := false;
3669
3670 app (fn (env, k, s1, s2) =>
3671 unifySummaries env (k, normalizeRecordSummary env s1, normalizeRecordSummary env s2)
3672 handle CUnify' err => (ErrorMsg.errorAt (#2 k) "Error in final record unification";
3673 cunifyError env err))
3674 (!delayedUnifs);
3675 delayedUnifs := [];
3676
3677 if ErrorMsg.anyErrors () then
3678 ()
3679 else
3680 app (fn f => f ()) (!checks);
3681
3639 if ErrorMsg.anyErrors () then 3682 if ErrorMsg.anyErrors () then
3640 () 3683 ()
3641 else 3684 else
3642 app (fn Disjoint (loc, env, denv, c1, c2) => 3685 app (fn Disjoint (loc, env, denv, c1, c2) =>
3643 (case D.prove env denv (c1, c2, loc) of 3686 (case D.prove env denv (c1, c2, loc) of