comparison src/elaborate.sml @ 90:94ef20a31550

Fancier head normalization pushed inside of Disjoint
author Adam Chlipala <adamc@hcoop.net>
date Thu, 03 Jul 2008 11:04:25 -0400
parents 7bab29834cd6
children 4327abd52997
comparison
equal deleted inserted replaced
89:d3ee072fa609 90:94ef20a31550
249 val (c2', k2, gs2) = elabCon (env, denv) c2 249 val (c2', k2, gs2) = elabCon (env, denv) c2
250 250
251 val ku1 = kunif loc 251 val ku1 = kunif loc
252 val ku2 = kunif loc 252 val ku2 = kunif loc
253 253
254 val denv' = D.assert env denv (c1', c2') 254 val (denv', gs3) = D.assert env denv (c1', c2')
255 val (c', k, gs3) = elabCon (env, denv') c 255 val (c', k, gs4) = elabCon (env, denv') c
256 in 256 in
257 checkKind env c1' k1 (L'.KRecord ku1, loc); 257 checkKind env c1' k1 (L'.KRecord ku1, loc);
258 checkKind env c2' k2 (L'.KRecord ku2, loc); 258 checkKind env c2' k2 (L'.KRecord ku2, loc);
259 259
260 ((L'.TDisjoint (c1', c2', c'), loc), k, gs1 @ gs2 @ gs3) 260 ((L'.TDisjoint (c1', c2', c'), loc), k, gs1 @ gs2 @ gs3 @ gs4)
261 end 261 end
262 | L.TRecord c => 262 | L.TRecord c =>
263 let 263 let
264 val (c', ck, gs) = elabCon (env, denv) c 264 val (c', ck, gs) = elabCon (env, denv) c
265 val k = (L'.KRecord ktype, loc) 265 val k = (L'.KRecord ktype, loc)
328 val (c2', k2, gs2) = elabCon (env, denv) c2 328 val (c2', k2, gs2) = elabCon (env, denv) c2
329 329
330 val ku1 = kunif loc 330 val ku1 = kunif loc
331 val ku2 = kunif loc 331 val ku2 = kunif loc
332 332
333 val denv' = D.assert env denv (c1', c2') 333 val (denv', gs3) = D.assert env denv (c1', c2')
334 val (c', k, gs3) = elabCon (env, denv') c 334 val (c', k, gs4) = elabCon (env, denv') c
335 in 335 in
336 checkKind env c1' k1 (L'.KRecord ku1, loc); 336 checkKind env c1' k1 (L'.KRecord ku1, loc);
337 checkKind env c2' k2 (L'.KRecord ku2, loc); 337 checkKind env c2' k2 (L'.KRecord ku2, loc);
338 338
339 ((L'.CDisjoint (c1', c2', c'), loc), k, gs1 @ gs2 @ gs3) 339 ((L'.CDisjoint (c1', c2', c'), loc), k, gs1 @ gs2 @ gs3 @ gs4)
340 end 340 end
341 341
342 | L.CName s => 342 | L.CName s =>
343 ((L'.CName s, loc), kname, []) 343 ((L'.CName s, loc), kname, [])
344 344
367 val r1 = (L'.CRecord (k, [xc]), loc) 367 val r1 = (L'.CRecord (k, [xc]), loc)
368 val ds = foldl (fn (xc', ds) => 368 val ds = foldl (fn (xc', ds) =>
369 let 369 let
370 val r2 = (L'.CRecord (k, [xc']), loc) 370 val r2 = (L'.CRecord (k, [xc']), loc)
371 in 371 in
372 map (fn cs => (loc, env, denv, cs)) (D.prove env denv (r1, r2, loc)) 372 D.prove env denv (r1, r2, loc) @ ds
373 @ ds
374 end) 373 end)
375 ds rest 374 ds rest
376 in 375 in
377 prove (rest, ds) 376 prove (rest, ds)
378 end 377 end
387 val k = (L'.KRecord ku, loc) 386 val k = (L'.KRecord ku, loc)
388 in 387 in
389 checkKind env c1' k1 k; 388 checkKind env c1' k1 k;
390 checkKind env c2' k2 k; 389 checkKind env c2' k2 k;
391 ((L'.CConcat (c1', c2'), loc), k, 390 ((L'.CConcat (c1', c2'), loc), k,
392 map (fn cs => (loc, env, denv, cs)) (D.prove env denv (c1', c2', loc)) @ gs1 @ gs2) 391 D.prove env denv (c1', c2', loc) @ gs1 @ gs2)
393 end 392 end
394 | L.CFold => 393 | L.CFold =>
395 let 394 let
396 val dom = kunif loc 395 val dom = kunif loc
397 val ran = kunif loc 396 val ran = kunif loc
543 | L'.CUnit => (L'.KUnit, loc) 542 | L'.CUnit => (L'.KUnit, loc)
544 543
545 | L'.CError => kerror 544 | L'.CError => kerror
546 | L'.CUnif (_, k, _, _) => k 545 | L'.CUnif (_, k, _, _) => k
547 546
548 fun hnormCon (env, denv) c = 547 val hnormCon = D.hnormCon
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 548
566 fun unifyRecordCons (env, denv) (c1, c2) = 549 fun unifyRecordCons (env, denv) (c1, c2) =
567 let 550 let
568 val k1 = kindof env c1 551 val k1 = kindof env c1
569 val k2 = kindof env c2 552 val k2 = kindof env c2
701 684
702 and unifyCons' (env, denv) c1 c2 = 685 and unifyCons' (env, denv) c1 c2 =
703 let 686 let
704 val (c1, gs1) = hnormCon (env, denv) c1 687 val (c1, gs1) = hnormCon (env, denv) c1
705 val (c2, gs2) = hnormCon (env, denv) c2 688 val (c2, gs2) = hnormCon (env, denv) c2
689 val gs3 = unifyCons'' (env, denv) c1 c2
706 in 690 in
707 unifyCons'' (env, denv) c1 c2; 691 gs1 @ gs2 @ gs3
708 gs1 @ gs2
709 end 692 end
710 693
711 and unifyCons'' (env, denv) (c1All as (c1, _)) (c2All as (c2, _)) = 694 and unifyCons'' (env, denv) (c1All as (c1, _)) (c2All as (c2, _)) =
712 let 695 let
713 fun err f = raise CUnify' (f (c1All, c2All)) 696 fun err f = raise CUnify' (f (c1All, c2All))
1038 val (c2', k2, gs2) = elabCon (env, denv) c2 1021 val (c2', k2, gs2) = elabCon (env, denv) c2
1039 1022
1040 val ku1 = kunif loc 1023 val ku1 = kunif loc
1041 val ku2 = kunif loc 1024 val ku2 = kunif loc
1042 1025
1043 val denv' = D.assert env denv (c1', c2') 1026 val (denv', gs3) = D.assert env denv (c1', c2')
1044 val (e', t, gs3) = elabExp (env, denv') e 1027 val (e', t, gs4) = elabExp (env, denv') e
1045 in 1028 in
1046 checkKind env c1' k1 (L'.KRecord ku1, loc); 1029 checkKind env c1' k1 (L'.KRecord ku1, loc);
1047 checkKind env c2' k2 (L'.KRecord ku2, loc); 1030 checkKind env c2' k2 (L'.KRecord ku2, loc);
1048 1031
1049 (e', (L'.TDisjoint (c1', c2', t), loc), gs1 @ gs2 @ gs3) 1032 (e', (L'.TDisjoint (c1', c2', t), loc), gs1 @ gs2 @ gs3 @ gs4)
1050 end 1033 end
1051 1034
1052 | L.ERecord xes => 1035 | L.ERecord xes =>
1053 let 1036 let
1054 val (xes', gs) = ListUtil.foldlMap (fn ((x, e), gs) => 1037 val (xes', gs) = ListUtil.foldlMap (fn ((x, e), gs) =>
1073 val gs = foldl (fn ((x', _, t'), gs) => 1056 val gs = foldl (fn ((x', _, t'), gs) =>
1074 let 1057 let
1075 val xc' = (x', t') 1058 val xc' = (x', t')
1076 val r2 = (L'.CRecord (k, [xc']), loc) 1059 val r2 = (L'.CRecord (k, [xc']), loc)
1077 in 1060 in
1078 map (fn cs => (loc, env, denv, cs)) (D.prove env denv (r1, r2, loc)) 1061 D.prove env denv (r1, r2, loc) @ gs
1079 @ gs
1080 end) 1062 end)
1081 gs rest 1063 gs rest
1082 in 1064 in
1083 prove (rest, gs) 1065 prove (rest, gs)
1084 end 1066 end
1098 val first = (L'.CRecord (ktype, [(c', ft)]), loc) 1080 val first = (L'.CRecord (ktype, [(c', ft)]), loc)
1099 1081
1100 val gs3 = 1082 val gs3 =
1101 checkCon (env, denv) e' et 1083 checkCon (env, denv) e' et
1102 (L'.TRecord (L'.CConcat (first, rest), loc), loc) 1084 (L'.TRecord (L'.CConcat (first, rest), loc), loc)
1103 val gs4 = 1085 val gs4 = D.prove env denv (first, rest, loc)
1104 map (fn cs => (loc, env, denv, cs))
1105 (D.prove env denv (first, rest, loc))
1106 in 1086 in
1107 ((L'.EField (e', c', {field = ft, rest = rest}), loc), ft, gs1 @ gs2 @ gs3 @ gs4) 1087 ((L'.EField (e', c', {field = ft, rest = rest}), loc), ft, gs1 @ gs2 @ gs3 @ gs4)
1108 end 1088 end
1109 1089
1110 | L.EFold => 1090 | L.EFold =>
1285 | L.SgiConstraint (c1, c2) => 1265 | L.SgiConstraint (c1, c2) =>
1286 let 1266 let
1287 val (c1', k1, gs1) = elabCon (env, denv) c1 1267 val (c1', k1, gs1) = elabCon (env, denv) c1
1288 val (c2', k2, gs2) = elabCon (env, denv) c2 1268 val (c2', k2, gs2) = elabCon (env, denv) c2
1289 1269
1290 val denv = D.assert env denv (c1', c2') 1270 val (denv, gs3) = D.assert env denv (c1', c2')
1291 in 1271 in
1292 checkKind env c1' k1 (L'.KRecord (kunif loc), loc); 1272 checkKind env c1' k1 (L'.KRecord (kunif loc), loc);
1293 checkKind env c2' k2 (L'.KRecord (kunif loc), loc); 1273 checkKind env c2' k2 (L'.KRecord (kunif loc), loc);
1294 1274
1295 ([(L'.SgiConstraint (c1', c2'), loc)], (env, denv, gs1 @ gs2)) 1275 ([(L'.SgiConstraint (c1', c2'), loc)], (env, denv, gs1 @ gs2 @ gs3))
1296 end 1276 end
1297 1277
1298 and elabSgn (env, denv) (sgn, loc) = 1278 and elabSgn (env, denv) (sgn, loc) =
1299 case sgn of 1279 case sgn of
1300 L.SgnConst sgis => 1280 L.SgnConst sgis =>
1482 val cso = E.projectConstraints env {sgn = sgn, str = st} 1462 val cso = E.projectConstraints env {sgn = sgn, str = st}
1483 1463
1484 val denv = case cso of 1464 val denv = case cso of
1485 NONE => (strError env (UnboundStr (loc, str)); 1465 NONE => (strError env (UnboundStr (loc, str));
1486 denv) 1466 denv)
1487 | SOME cs => foldl (fn ((c1, c2), denv) => D.assert env denv (c1, c2)) denv cs 1467 | SOME cs => foldl (fn ((c1, c2), denv) =>
1468 let
1469 val (denv, gs) = D.assert env denv (c1, c2)
1470 in
1471 case gs of
1472 [] => ()
1473 | _ => raise Fail "dopenConstraints: Sub-constraints remain";
1474
1475 denv
1476 end) denv cs
1488 in 1477 in
1489 denv 1478 denv
1490 end 1479 end
1491 1480
1492 fun sgiOfDecl (d, loc) = 1481 fun sgiOfDecl (d, loc) =
1498 | L'.DFfiStr (x, n, sgn) => (L'.SgiStr (x, n, sgn), loc) 1487 | L'.DFfiStr (x, n, sgn) => (L'.SgiStr (x, n, sgn), loc)
1499 | L'.DConstraint cs => (L'.SgiConstraint cs, loc) 1488 | L'.DConstraint cs => (L'.SgiConstraint cs, loc)
1500 1489
1501 fun sgiBindsD (env, denv) (sgi, _) = 1490 fun sgiBindsD (env, denv) (sgi, _) =
1502 case sgi of 1491 case sgi of
1503 L'.SgiConstraint (c1, c2) => D.assert env denv (c1, c2) 1492 L'.SgiConstraint (c1, c2) =>
1493 (case D.assert env denv (c1, c2) of
1494 (denv, []) => denv
1495 | _ => raise Fail "sgiBindsD: Sub-constraints remain")
1504 | _ => denv 1496 | _ => denv
1505 1497
1506 fun subSgn (env, denv) sgn1 (sgn2 as (_, loc2)) = 1498 fun subSgn (env, denv) sgn1 (sgn2 as (_, loc2)) =
1507 case (#1 (hnormSgn env sgn1), #1 (hnormSgn env sgn2)) of 1499 case (#1 (hnormSgn env sgn1), #1 (hnormSgn env sgn2)) of
1508 (L'.SgnError, _) => () 1500 (L'.SgnError, _) => ()
1632 | L'.SgiConstraint (c2, d2) => 1624 | L'.SgiConstraint (c2, d2) =>
1633 seek (fn sgi1All as (sgi1, _) => 1625 seek (fn sgi1All as (sgi1, _) =>
1634 case sgi1 of 1626 case sgi1 of
1635 L'.SgiConstraint (c1, d1) => 1627 L'.SgiConstraint (c1, d1) =>
1636 if consEq (env, denv) (c1, c2) andalso consEq (env, denv) (d1, d2) then 1628 if consEq (env, denv) (c1, c2) andalso consEq (env, denv) (d1, d2) then
1637 SOME (env, D.assert env denv (c2, d2)) 1629 let
1630 val (denv, gs) = D.assert env denv (c2, d2)
1631 in
1632 case gs of
1633 [] => ()
1634 | _ => raise Fail "subSgn: Sub-constraints remain";
1635
1636 SOME (env, denv)
1637 end
1638 else 1638 else
1639 NONE 1639 NONE
1640 | _ => NONE) 1640 | _ => NONE)
1641 end 1641 end
1642 in 1642 in
1791 1791
1792 | L.DConstraint (c1, c2) => 1792 | L.DConstraint (c1, c2) =>
1793 let 1793 let
1794 val (c1', k1, gs1) = elabCon (env, denv) c1 1794 val (c1', k1, gs1) = elabCon (env, denv) c1
1795 val (c2', k2, gs2) = elabCon (env, denv) c2 1795 val (c2', k2, gs2) = elabCon (env, denv) c2
1796 val gs3 = map (fn cs => (loc, env, denv, cs)) (D.prove env denv (c1', c2', loc)) 1796 val gs3 = D.prove env denv (c1', c2', loc)
1797 1797
1798 val denv' = D.assert env denv (c1', c2') 1798 val (denv', gs4) = D.assert env denv (c1', c2')
1799 in 1799 in
1800 checkKind env c1' k1 (L'.KRecord (kunif loc), loc); 1800 checkKind env c1' k1 (L'.KRecord (kunif loc), loc);
1801 checkKind env c2' k2 (L'.KRecord (kunif loc), loc); 1801 checkKind env c2' k2 (L'.KRecord (kunif loc), loc);
1802 1802
1803 ([(L'.DConstraint (c1', c2'), loc)], (env, denv', gs1 @ gs2 @ gs3)) 1803 ([(L'.DConstraint (c1', c2'), loc)], (env, denv', gs1 @ gs2 @ gs3 @ gs4))
1804 end 1804 end
1805 1805
1806 | L.DOpenConstraints (m, ms) => 1806 | L.DOpenConstraints (m, ms) =>
1807 let 1807 let
1808 val denv = dopenConstraints (loc, env, denv) {str = m, strs = ms} 1808 val denv = dopenConstraints (loc, env, denv) {str = m, strs = ms}
1980 val (file, (_, gs)) = ListUtil.foldlMapConcat elabDecl' (env', []) file 1980 val (file, (_, gs)) = ListUtil.foldlMapConcat elabDecl' (env', []) file
1981 in 1981 in
1982 if ErrorMsg.anyErrors () then 1982 if ErrorMsg.anyErrors () then
1983 () 1983 ()
1984 else 1984 else
1985 app (fn (loc, env, denv, (c1, c2)) => 1985 app (fn (loc, env, denv, c1, c2) =>
1986 case D.prove env denv (c1, c2, loc) of 1986 case D.prove env denv (c1, c2, loc) of
1987 [] => () 1987 [] => ()
1988 | _ => 1988 | _ =>
1989 (ErrorMsg.errorAt loc "Couldn't prove field name disjointness"; 1989 (ErrorMsg.errorAt loc "Couldn't prove field name disjointness";
1990 eprefaces' [("Con 1", p_con env c1), 1990 eprefaces' [("Con 1", p_con env c1),
1991 ("Con 2", p_con env c2)])) gs; 1991 ("Con 2", p_con env c2),
1992 ("Hnormed 1", p_con env (ElabOps.hnormCon env c1)),
1993 ("Hnormed 2", p_con env (ElabOps.hnormCon env c2))])) gs;
1992 1994
1993 (L'.DFfiStr ("Basis", basis_n, sgn), ErrorMsg.dummySpan) :: ds @ file 1995 (L'.DFfiStr ("Basis", basis_n, sgn), ErrorMsg.dummySpan) :: ds @ file
1994 end 1996 end
1995 1997
1996 end 1998 end