comparison src/elab_env.sml @ 805:e2780d2f4afc

Mutual datatypes through Elaborate
author Adam Chlipala <adamc@hcoop.net>
date Sat, 16 May 2009 15:14:17 -0400
parents 8688e01ae469
children 7f871c03e3a1
comparison
equal deleted inserted replaced
804:10fe57e4a8c2 805:e2780d2f4afc
907 907
908 fun sgiSeek (sgi, (sgns, strs, cons)) = 908 fun sgiSeek (sgi, (sgns, strs, cons)) =
909 case sgi of 909 case sgi of
910 SgiConAbs (x, n, _) => (sgns, strs, IM.insert (cons, n, x)) 910 SgiConAbs (x, n, _) => (sgns, strs, IM.insert (cons, n, x))
911 | SgiCon (x, n, _, _) => (sgns, strs, IM.insert (cons, n, x)) 911 | SgiCon (x, n, _, _) => (sgns, strs, IM.insert (cons, n, x))
912 | SgiDatatype (x, n, _, _) => (sgns, strs, IM.insert (cons, n, x)) 912 | SgiDatatype dts => (sgns, strs, foldl (fn ((x, n, _, _), cons) => IM.insert (cons, n, x)) cons dts)
913 | SgiDatatypeImp (x, n, _, _, _, _, _) => (sgns, strs, IM.insert (cons, n, x)) 913 | SgiDatatypeImp (x, n, _, _, _, _, _) => (sgns, strs, IM.insert (cons, n, x))
914 | SgiVal _ => (sgns, strs, cons) 914 | SgiVal _ => (sgns, strs, cons)
915 | SgiSgn (x, n, _) => (IM.insert (sgns, n, x), strs, cons) 915 | SgiSgn (x, n, _) => (IM.insert (sgns, n, x), strs, cons)
916 | SgiStr (x, n, _) => (sgns, IM.insert (strs, n, x), cons) 916 | SgiStr (x, n, _) => (sgns, IM.insert (strs, n, x), cons)
917 | SgiConstraint _ => (sgns, strs, cons) 917 | SgiConstraint _ => (sgns, strs, cons)
927 case f sgi of 927 case f sgi of
928 SOME v => 928 SOME v =>
929 let 929 let
930 val cons = 930 val cons =
931 case sgi of 931 case sgi of
932 SgiDatatype (x, n, _, _) => IM.insert (cons, n, x) 932 SgiDatatype dts => foldl (fn ((x, n, _, _), cons) => IM.insert (cons, n, x)) cons dts
933 | SgiDatatypeImp (x, n, _, _, _, _, _) => IM.insert (cons, n, x) 933 | SgiDatatypeImp (x, n, _, _, _, _, _) => IM.insert (cons, n, x)
934 | _ => cons 934 | _ => cons
935 in 935 in
936 SOME (v, (sgns, strs, cons)) 936 SOME (v, (sgns, strs, cons))
937 end 937 end
1207 1207
1208 fun sgiBinds env (sgi, loc) = 1208 fun sgiBinds env (sgi, loc) =
1209 case sgi of 1209 case sgi of
1210 SgiConAbs (x, n, k) => pushCNamedAs env x n k NONE 1210 SgiConAbs (x, n, k) => pushCNamedAs env x n k NONE
1211 | SgiCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) 1211 | SgiCon (x, n, k, c) => pushCNamedAs env x n k (SOME c)
1212 | SgiDatatype (x, n, xs, xncs) => 1212 | SgiDatatype dts =>
1213 let 1213 let
1214 val k = (KType, loc) 1214 fun doOne ((x, n, xs, xncs), env) =
1215 val k' = foldr (fn (_, k') => (KArrow (k, k'), loc)) k xs 1215 let
1216 1216 val k = (KType, loc)
1217 val env = pushCNamedAs env x n k' NONE 1217 val k' = foldr (fn (_, k') => (KArrow (k, k'), loc)) k xs
1218
1219 val env = pushCNamedAs env x n k' NONE
1220 in
1221 foldl (fn ((x', n', to), env) =>
1222 let
1223 val t =
1224 case to of
1225 NONE => (CNamed n, loc)
1226 | SOME t => (TFun (t, (CNamed n, loc)), loc)
1227
1228 val k = (KType, loc)
1229 val t = foldr (fn (x, t) => (TCFun (Explicit, x, k, t), loc)) t xs
1230 in
1231 pushENamedAs env x' n' t
1232 end)
1233 env xncs
1234 end
1218 in 1235 in
1219 foldl (fn ((x', n', to), env) => 1236 foldl doOne env dts
1220 let
1221 val t =
1222 case to of
1223 NONE => (CNamed n, loc)
1224 | SOME t => (TFun (t, (CNamed n, loc)), loc)
1225
1226 val k = (KType, loc)
1227 val t = foldr (fn (x, t) => (TCFun (Explicit, x, k, t), loc)) t xs
1228 in
1229 pushENamedAs env x' n' t
1230 end)
1231 env xncs
1232 end 1237 end
1233 | SgiDatatypeImp (x, n, m1, ms, x', xs, xncs) => 1238 | SgiDatatypeImp (x, n, m1, ms, x', xs, xncs) =>
1234 let 1239 let
1235 val k = (KType, loc) 1240 val k = (KType, loc)
1236 val k' = foldr (fn (_, k') => (KArrow (k, k'), loc)) k xs 1241 val k' = foldr (fn (_, k') => (KArrow (k, k'), loc)) k xs
1286 fun projectCon env {sgn, str, field} = 1291 fun projectCon env {sgn, str, field} =
1287 case #1 (hnormSgn env sgn) of 1292 case #1 (hnormSgn env sgn) of
1288 SgnConst sgis => 1293 SgnConst sgis =>
1289 (case sgnSeek (fn SgiConAbs (x, _, k) => if x = field then SOME (k, NONE) else NONE 1294 (case sgnSeek (fn SgiConAbs (x, _, k) => if x = field then SOME (k, NONE) else NONE
1290 | SgiCon (x, _, k, c) => if x = field then SOME (k, SOME c) else NONE 1295 | SgiCon (x, _, k, c) => if x = field then SOME (k, SOME c) else NONE
1291 | SgiDatatype (x, _, xs, _) => 1296 | SgiDatatype dts =>
1292 if x = field then 1297 (case List.find (fn (x, _, xs, _) => x = field) dts of
1293 let 1298 SOME (_, _, xs, _) =>
1294 val k = (KType, #2 sgn) 1299 let
1295 val k' = foldl (fn (_, k') => (KArrow (k, k'), #2 sgn)) k xs 1300 val k = (KType, #2 sgn)
1296 in 1301 val k' = foldl (fn (_, k') => (KArrow (k, k'), #2 sgn)) k xs
1297 SOME (k', NONE) 1302 in
1298 end 1303 SOME (k', NONE)
1299 else 1304 end
1300 NONE 1305 | NONE => NONE)
1301 | SgiDatatypeImp (x, _, m1, ms, x', xs, _) => 1306 | SgiDatatypeImp (x, _, m1, ms, x', xs, _) =>
1302 if x = field then 1307 if x = field then
1303 let 1308 let
1304 val k = (KType, #2 sgn) 1309 val k = (KType, #2 sgn)
1305 val k' = foldl (fn (_, k') => (KArrow (k, k'), #2 sgn)) k xs 1310 val k' = foldl (fn (_, k') => (KArrow (k, k'), #2 sgn)) k xs
1323 | _ => NONE 1328 | _ => NONE
1324 1329
1325 fun projectDatatype env {sgn, str, field} = 1330 fun projectDatatype env {sgn, str, field} =
1326 case #1 (hnormSgn env sgn) of 1331 case #1 (hnormSgn env sgn) of
1327 SgnConst sgis => 1332 SgnConst sgis =>
1328 (case sgnSeek (fn SgiDatatype (x, _, xs, xncs) => if x = field then SOME (xs, xncs) else NONE 1333 (case sgnSeek (fn SgiDatatype dts =>
1334 (case List.find (fn (x, _, _, _) => x = field) dts of
1335 SOME (_, _, xs, xncs) => SOME (xs, xncs)
1336 | NONE => NONE)
1329 | SgiDatatypeImp (x, _, _, _, _, xs, xncs) => if x = field then SOME (xs, xncs) else NONE 1337 | SgiDatatypeImp (x, _, _, _, _, xs, xncs) => if x = field then SOME (xs, xncs) else NONE
1330 | _ => NONE) sgis of 1338 | _ => NONE) sgis of
1331 NONE => NONE 1339 NONE => NONE
1332 | SOME ((xs, xncs), subs) => SOME (xs, 1340 | SOME ((xs, xncs), subs) => SOME (xs,
1333 map (fn (x, n, to) => (x, n, Option.map (sgnSubCon (str, subs)) to)) xncs)) 1341 map (fn (x, n, to) => (x, n, Option.map (sgnSubCon (str, subs)) to)) xncs))
1342 if x <> field then 1350 if x <> field then
1343 NONE 1351 NONE
1344 else 1352 else
1345 SOME (U.classifyDatatype xncs, n', xs, to, (CNamed n, #2 str))) xncs 1353 SOME (U.classifyDatatype xncs, n', xs, to, (CNamed n, #2 str))) xncs
1346 in 1354 in
1347 case sgnSeek (fn SgiDatatype (_, n, xs, xncs) => consider (n, xs, xncs) 1355 case sgnSeek (fn SgiDatatype dts =>
1356 let
1357 fun search dts =
1358 case dts of
1359 [] => NONE
1360 | (_, n, xs, xncs) :: dts =>
1361 case consider (n, xs, xncs) of
1362 NONE => search dts
1363 | v => v
1364 in
1365 search dts
1366 end
1348 | SgiDatatypeImp (_, n, _, _, _, xs, xncs) => consider (n, xs, xncs) 1367 | SgiDatatypeImp (_, n, _, _, _, xs, xncs) => consider (n, xs, xncs)
1349 | _ => NONE) sgis of 1368 | _ => NONE) sgis of
1350 NONE => NONE 1369 NONE => NONE
1351 | SOME ((dk, n, xs, to, t), subs) => SOME (dk, n, xs, Option.map (sgnSubCon (str, subs)) to, 1370 | SOME ((dk, n, xs, to, t), subs) => SOME (dk, n, xs, Option.map (sgnSubCon (str, subs)) to,
1352 sgnSubCon (str, subs) t) 1371 sgnSubCon (str, subs) t)
1380 end) 1399 end)
1381 else 1400 else
1382 NONE) xncs 1401 NONE) xncs
1383 in 1402 in
1384 case sgnSeek (fn SgiVal (x, _, c) => if x = field then SOME c else NONE 1403 case sgnSeek (fn SgiVal (x, _, c) => if x = field then SOME c else NONE
1385 | SgiDatatype (_, n, xs, xncs) => seek (n, xs, xncs) 1404 | SgiDatatype dts =>
1405 let
1406 fun search dts =
1407 case dts of
1408 [] => NONE
1409 | (_, n, xs, xncs) :: dts =>
1410 case seek (n, xs, xncs) of
1411 NONE => search dts
1412 | v => v
1413 in
1414 search dts
1415 end
1386 | SgiDatatypeImp (_, n, _, _, _, xs, xncs) => seek (n, xs, xncs) 1416 | SgiDatatypeImp (_, n, _, _, _, xs, xncs) => seek (n, xs, xncs)
1387 | _ => NONE) sgis of 1417 | _ => NONE) sgis of
1388 NONE => NONE 1418 NONE => NONE
1389 | SOME (c, subs) => SOME (sgnSubCon (str, subs) c) 1419 | SOME (c, subs) => SOME (sgnSubCon (str, subs) c)
1390 end 1420 end
1404 in 1434 in
1405 seek (sgis, sgns, strs, cons, (sub c1, sub c2) :: acc) 1435 seek (sgis, sgns, strs, cons, (sub c1, sub c2) :: acc)
1406 end 1436 end
1407 | SgiConAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) 1437 | SgiConAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc)
1408 | SgiCon (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) 1438 | SgiCon (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc)
1409 | SgiDatatype (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) 1439 | SgiDatatype dts => seek (sgis, sgns, strs,
1440 foldl (fn ((x, n, _, _), cons) => IM.insert (cons, n, x)) cons dts, acc)
1410 | SgiDatatypeImp (x, n, _, _, _, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) 1441 | SgiDatatypeImp (x, n, _, _, _, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc)
1411 | SgiVal _ => seek (sgis, sgns, strs, cons, acc) 1442 | SgiVal _ => seek (sgis, sgns, strs, cons, acc)
1412 | SgiSgn (x, n, _) => seek (sgis, IM.insert (sgns, n, x), strs, cons, acc) 1443 | SgiSgn (x, n, _) => seek (sgis, IM.insert (sgns, n, x), strs, cons, acc)
1413 | SgiStr (x, n, _) => seek (sgis, sgns, IM.insert (strs, n, x), cons, acc) 1444 | SgiStr (x, n, _) => seek (sgis, sgns, IM.insert (strs, n, x), cons, acc)
1414 | SgiClassAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) 1445 | SgiClassAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc)
1429 | EDValRec vis => foldl (fn ((x, t, _), env) => pushERel env x t) env vis 1460 | EDValRec vis => foldl (fn ((x, t, _), env) => pushERel env x t) env vis
1430 1461
1431 fun declBinds env (d, loc) = 1462 fun declBinds env (d, loc) =
1432 case d of 1463 case d of
1433 DCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) 1464 DCon (x, n, k, c) => pushCNamedAs env x n k (SOME c)
1434 | DDatatype (x, n, xs, xncs) => 1465 | DDatatype dts =>
1435 let 1466 let
1436 val k = (KType, loc) 1467 fun doOne ((x, n, xs, xncs), env) =
1437 val nxs = length xs 1468 let
1438 val (tb, kb) = ListUtil.foldli (fn (i, x', (tb, kb)) => 1469 val k = (KType, loc)
1439 ((CApp (tb, (CRel (nxs - i - 1), loc)), loc), 1470 val nxs = length xs
1440 (KArrow (k, kb), loc))) 1471 val (tb, kb) = ListUtil.foldli (fn (i, x', (tb, kb)) =>
1441 ((CNamed n, loc), k) xs 1472 ((CApp (tb, (CRel (nxs - i - 1), loc)), loc),
1442 1473 (KArrow (k, kb), loc)))
1443 val env = pushCNamedAs env x n kb NONE 1474 ((CNamed n, loc), k) xs
1444 val env = pushDatatype env n xs xncs 1475
1476 val env = pushCNamedAs env x n kb NONE
1477 val env = pushDatatype env n xs xncs
1478 in
1479 foldl (fn ((x', n', to), env) =>
1480 let
1481 val t =
1482 case to of
1483 NONE => tb
1484 | SOME t => (TFun (t, tb), loc)
1485 val t = foldr (fn (x, t) => (TCFun (Implicit, x, k, t), loc)) t xs
1486 in
1487 pushENamedAs env x' n' t
1488 end)
1489 env xncs
1490 end
1445 in 1491 in
1446 foldl (fn ((x', n', to), env) => 1492 foldl doOne env dts
1447 let
1448 val t =
1449 case to of
1450 NONE => tb
1451 | SOME t => (TFun (t, tb), loc)
1452 val t = foldr (fn (x, t) => (TCFun (Implicit, x, k, t), loc)) t xs
1453 in
1454 pushENamedAs env x' n' t
1455 end)
1456 env xncs
1457 end 1493 end
1458 | DDatatypeImp (x, n, m, ms, x', xs, xncs) => 1494 | DDatatypeImp (x, n, m, ms, x', xs, xncs) =>
1459 let 1495 let
1460 val t = (CModProj (m, ms, x'), loc) 1496 val t = (CModProj (m, ms, x'), loc)
1461 val k = (KType, loc) 1497 val k = (KType, loc)