Mercurial > urweb
comparison src/elab_env.sml @ 1303:c7b9a33c26c8
Hopeful fix for the Great Unification Bug
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sun, 10 Oct 2010 14:41:03 -0400 |
parents | b4480a56cab7 |
children | fdf48f6ba418 |
comparison
equal
deleted
inserted
replaced
1302:d008c4c43a0a | 1303:c7b9a33c26c8 |
---|---|
41 exception UnboundNamed of int | 41 exception UnboundNamed of int |
42 | 42 |
43 | 43 |
44 (* AST utility functions *) | 44 (* AST utility functions *) |
45 | 45 |
46 exception SynUnif | |
47 | |
48 val liftKindInKind = | 46 val liftKindInKind = |
49 U.Kind.mapB {kind = fn bound => fn k => | 47 U.Kind.mapB {kind = fn bound => fn k => |
50 case k of | 48 case k of |
51 KRel xn => | 49 KRel xn => |
52 if xn < bound then | 50 if xn < bound then |
76 CRel xn => | 74 CRel xn => |
77 if xn < bound then | 75 if xn < bound then |
78 c | 76 c |
79 else | 77 else |
80 CRel (xn + 1) | 78 CRel (xn + 1) |
81 (*| CUnif _ => raise SynUnif*) | 79 | CUnif (nl, loc, k, s, r) => CUnif (nl+1, loc, k, s, r) |
82 | _ => c, | 80 | _ => c, |
83 bind = fn (bound, U.Con.RelC _) => bound + 1 | 81 bind = fn (bound, U.Con.RelC _) => bound + 1 |
84 | (bound, _) => bound} | 82 | (bound, _) => bound} |
85 | 83 |
86 val lift = liftConInCon 0 | 84 val lift = liftConInCon 0 |
85 | |
86 fun mliftConInCon by c = | |
87 if by = 0 then | |
88 c | |
89 else | |
90 U.Con.mapB {kind = fn _ => fn k => k, | |
91 con = fn bound => fn c => | |
92 case c of | |
93 CRel xn => | |
94 if xn < bound then | |
95 c | |
96 else | |
97 CRel (xn + by) | |
98 | CUnif (nl, loc, k, s, r) => CUnif (nl+by, loc, k, s, r) | |
99 | _ => c, | |
100 bind = fn (bound, U.Con.RelC _) => bound + 1 | |
101 | (bound, _) => bound} 0 c | |
102 | |
103 val () = U.mliftConInCon := mliftConInCon | |
87 | 104 |
88 val liftKindInExp = | 105 val liftKindInExp = |
89 U.Exp.mapB {kind = fn bound => fn k => | 106 U.Exp.mapB {kind = fn bound => fn k => |
90 case k of | 107 case k of |
91 KRel xn => | 108 KRel xn => |
106 CRel xn => | 123 CRel xn => |
107 if xn < bound then | 124 if xn < bound then |
108 c | 125 c |
109 else | 126 else |
110 CRel (xn + 1) | 127 CRel (xn + 1) |
128 | CUnif (nl, loc, k, s, r) => CUnif (nl+1, loc, k, s, r) | |
111 | _ => c, | 129 | _ => c, |
112 exp = fn _ => fn e => e, | 130 exp = fn _ => fn e => e, |
113 bind = fn (bound, U.Exp.RelC _) => bound + 1 | 131 bind = fn (bound, U.Exp.RelC _) => bound + 1 |
114 | (bound, _) => bound} | 132 | (bound, _) => bound} |
115 | 133 |
464 | 482 |
465 fun class_name_in (c, _) = | 483 fun class_name_in (c, _) = |
466 case c of | 484 case c of |
467 CNamed n => SOME (ClNamed n) | 485 CNamed n => SOME (ClNamed n) |
468 | CModProj x => SOME (ClProj x) | 486 | CModProj x => SOME (ClProj x) |
469 | CUnif (_, _, _, ref (SOME c)) => class_name_in c | 487 | CUnif (_, _, _, _, ref (SOME c)) => class_name_in c |
470 | _ => NONE | 488 | _ => NONE |
471 | 489 |
472 fun isClass (env : env) c = | 490 fun isClass (env : env) c = |
473 let | 491 let |
474 fun find NONE = false | 492 fun find NONE = false |
478 end | 496 end |
479 | 497 |
480 fun class_head_in c = | 498 fun class_head_in c = |
481 case #1 c of | 499 case #1 c of |
482 CApp (f, _) => class_head_in f | 500 CApp (f, _) => class_head_in f |
483 | CUnif (_, _, _, ref (SOME c)) => class_head_in c | 501 | CUnif (_, _, _, _, ref (SOME c)) => class_head_in c |
484 | _ => class_name_in c | 502 | _ => class_name_in c |
485 | 503 |
486 exception Unify | 504 exception Unify |
487 | 505 |
488 fun unifyKinds (k1, k2) = | 506 fun unifyKinds (k1, k2) = |
500 | (KFun (_, k1), KFun (_, k2)) => unifyKinds (k1, k2) | 518 | (KFun (_, k1), KFun (_, k2)) => unifyKinds (k1, k2) |
501 | _ => raise Unify | 519 | _ => raise Unify |
502 | 520 |
503 fun eqCons (c1, c2) = | 521 fun eqCons (c1, c2) = |
504 case (#1 c1, #1 c2) of | 522 case (#1 c1, #1 c2) of |
505 (CUnif (_, _, _, ref (SOME c1)), _) => eqCons (c1, c2) | 523 (CUnif (nl, _, _, _, ref (SOME c1)), _) => eqCons (mliftConInCon nl c1, c2) |
506 | (_, CUnif (_, _, _, ref (SOME c2))) => eqCons (c1, c2) | 524 | (_, CUnif (nl, _, _, _, ref (SOME c2))) => eqCons (c1, mliftConInCon nl c2) |
507 | 525 |
508 | (CRel n1, CRel n2) => if n1 = n2 then () else raise Unify | 526 | (CRel n1, CRel n2) => if n1 = n2 then () else raise Unify |
509 | 527 |
510 | (TFun (d1, r1), TFun (d2, r2)) => (eqCons (d1, d2); eqCons (r1, r2)) | 528 | (TFun (d1, r1), TFun (d2, r2)) => (eqCons (d1, d2); eqCons (r1, r2)) |
511 | (TCFun (_, _, k1, r1), TCFun (_, _, k2, r2)) => (unifyKinds (k1, k2); eqCons (r1, r2)) | 529 | (TCFun (_, _, k1, r1), TCFun (_, _, k2, r2)) => (unifyKinds (k1, k2); eqCons (r1, r2)) |
543 | 561 |
544 fun unifyCons rs = | 562 fun unifyCons rs = |
545 let | 563 let |
546 fun unify d (c1, c2) = | 564 fun unify d (c1, c2) = |
547 case (#1 c1, #1 c2) of | 565 case (#1 c1, #1 c2) of |
548 (CUnif (_, _, _, ref (SOME c1)), _) => unify d (c1, c2) | 566 (CUnif (nl, _, _, _, ref (SOME c1)), _) => unify d (mliftConInCon nl c1, c2) |
549 | (_, CUnif (_, _, _, ref (SOME c2))) => unify d (c1, c2) | 567 | (_, CUnif (nl, _, _, _, ref (SOME c2))) => unify d (c1, mliftConInCon nl c2) |
550 | 568 |
551 | (CUnif _, _) => () | 569 | (CUnif _, _) => () |
552 | 570 |
553 | (c1', CRel n2) => | 571 | (c1', CRel n2) => |
554 if n2 < d then | 572 if n2 < d then |
631 0 | 649 0 |
632 | 650 |
633 exception Bad of con * con | 651 exception Bad of con * con |
634 | 652 |
635 val hasUnif = U.Con.exists {kind = fn _ => false, | 653 val hasUnif = U.Con.exists {kind = fn _ => false, |
636 con = fn CUnif (_, _, _, ref NONE) => true | 654 con = fn CUnif (_, _, _, _, ref NONE) => true |
637 | _ => false} | 655 | _ => false} |
638 | 656 |
639 fun startsWithUnif c = | 657 fun startsWithUnif c = |
640 let | 658 let |
641 fun firstArg (c, acc) = | 659 fun firstArg (c, acc) = |
668 fun isRecord () = | 686 fun isRecord () = |
669 let | 687 let |
670 val rk = ref NONE | 688 val rk = ref NONE |
671 val k = (KUnif (loc, "k", rk), loc) | 689 val k = (KUnif (loc, "k", rk), loc) |
672 val r = ref NONE | 690 val r = ref NONE |
673 val rc = (CUnif (loc, k, "x", r), loc) | 691 val rc = (CUnif (0, loc, k, "x", r), loc) |
674 in | 692 in |
675 ((CApp (f, rc), loc), | 693 ((CApp (f, rc), loc), |
676 fn () => (if consEq (rc, x) then | 694 fn () => (if consEq (rc, x) then |
677 true | 695 true |
678 else | 696 else |