comparison src/elaborate.sml @ 469:b393c2fc80f8

About to begin optimization of recursive transaction functions
author Adam Chlipala <adamc@hcoop.net>
date Thu, 06 Nov 2008 17:09:53 -0500
parents 3f1b9231a37b
children 20fab0e96217
comparison
equal deleted inserted replaced
468:4efab85405be 469:b393c2fc80f8
1774 val hnormSgn = E.hnormSgn 1774 val hnormSgn = E.hnormSgn
1775 1775
1776 fun tableOf () = (L'.CModProj (!basis_r, [], "sql_table"), ErrorMsg.dummySpan) 1776 fun tableOf () = (L'.CModProj (!basis_r, [], "sql_table"), ErrorMsg.dummySpan)
1777 fun sequenceOf () = (L'.CModProj (!basis_r, [], "sql_sequence"), ErrorMsg.dummySpan) 1777 fun sequenceOf () = (L'.CModProj (!basis_r, [], "sql_sequence"), ErrorMsg.dummySpan)
1778 fun cookieOf () = (L'.CModProj (!basis_r, [], "http_cookie"), ErrorMsg.dummySpan) 1778 fun cookieOf () = (L'.CModProj (!basis_r, [], "http_cookie"), ErrorMsg.dummySpan)
1779
1780 fun dopenConstraints (loc, env, denv) {str, strs} =
1781 case E.lookupStr env str of
1782 NONE => (strError env (UnboundStr (loc, str));
1783 denv)
1784 | SOME (n, sgn) =>
1785 let
1786 val (st, sgn) = foldl (fn (m, (str, sgn)) =>
1787 case E.projectStr env {str = str, sgn = sgn, field = m} of
1788 NONE => (strError env (UnboundStr (loc, m));
1789 (strerror, sgnerror))
1790 | SOME sgn => ((L'.StrProj (str, m), loc), sgn))
1791 ((L'.StrVar n, loc), sgn) strs
1792
1793 val cso = E.projectConstraints env {sgn = sgn, str = st}
1794
1795 val denv = case cso of
1796 NONE => (strError env (UnboundStr (loc, str));
1797 denv)
1798 | SOME cs => foldl (fn ((c1, c2), denv) =>
1799 let
1800 val (denv, gs) = D.assert env denv (c1, c2)
1801 in
1802 case gs of
1803 [] => ()
1804 | _ => raise Fail "dopenConstraints: Sub-constraints remain";
1805
1806 denv
1807 end) denv cs
1808 in
1809 denv
1810 end
1779 1811
1780 fun elabSgn_item ((sgi, loc), (env, denv, gs)) = 1812 fun elabSgn_item ((sgi, loc), (env, denv, gs)) =
1781 case sgi of 1813 case sgi of
1782 L.SgiConAbs (x, k) => 1814 L.SgiConAbs (x, k) =>
1783 let 1815 let
2052 | SOME (n, sgis) => ((L'.SgnVar n, loc), [])) 2084 | SOME (n, sgis) => ((L'.SgnVar n, loc), []))
2053 | L.SgnFun (m, dom, ran) => 2085 | L.SgnFun (m, dom, ran) =>
2054 let 2086 let
2055 val (dom', gs1) = elabSgn (env, denv) dom 2087 val (dom', gs1) = elabSgn (env, denv) dom
2056 val (env', n) = E.pushStrNamed env m dom' 2088 val (env', n) = E.pushStrNamed env m dom'
2057 val (ran', gs2) = elabSgn (env', denv) ran 2089 val denv' = dopenConstraints (loc, env', denv) {str = m, strs = []}
2090 val (ran', gs2) = elabSgn (env', denv') ran
2058 in 2091 in
2059 ((L'.SgnFun (m, n, dom', ran'), loc), gs1 @ gs2) 2092 ((L'.SgnFun (m, n, dom', ran'), loc), gs1 @ gs2)
2060 end 2093 end
2061 | L.SgnWhere (sgn, x, c) => 2094 | L.SgnWhere (sgn, x, c) =>
2062 let 2095 let
2191 (env, denv) sgis 2224 (env, denv) sgis
2192 | _ => (strError env (UnOpenable sgn); 2225 | _ => (strError env (UnOpenable sgn);
2193 ([], (env, denv))) 2226 ([], (env, denv)))
2194 end 2227 end
2195 2228
2196 fun dopenConstraints (loc, env, denv) {str, strs} =
2197 case E.lookupStr env str of
2198 NONE => (strError env (UnboundStr (loc, str));
2199 denv)
2200 | SOME (n, sgn) =>
2201 let
2202 val (st, sgn) = foldl (fn (m, (str, sgn)) =>
2203 case E.projectStr env {str = str, sgn = sgn, field = m} of
2204 NONE => (strError env (UnboundStr (loc, m));
2205 (strerror, sgnerror))
2206 | SOME sgn => ((L'.StrProj (str, m), loc), sgn))
2207 ((L'.StrVar n, loc), sgn) strs
2208
2209 val cso = E.projectConstraints env {sgn = sgn, str = st}
2210
2211 val denv = case cso of
2212 NONE => (strError env (UnboundStr (loc, str));
2213 denv)
2214 | SOME cs => foldl (fn ((c1, c2), denv) =>
2215 let
2216 val (denv, gs) = D.assert env denv (c1, c2)
2217 in
2218 case gs of
2219 [] => ()
2220 | _ => raise Fail "dopenConstraints: Sub-constraints remain";
2221
2222 denv
2223 end) denv cs
2224 in
2225 denv
2226 end
2227
2228 fun sgiOfDecl (d, loc) = 2229 fun sgiOfDecl (d, loc) =
2229 case d of 2230 case d of
2230 L'.DCon (x, n, k, c) => [(L'.SgiCon (x, n, k, c), loc)] 2231 L'.DCon (x, n, k, c) => [(L'.SgiCon (x, n, k, c), loc)]
2231 | L'.DDatatype x => [(L'.SgiDatatype x, loc)] 2232 | L'.DDatatype x => [(L'.SgiDatatype x, loc)]
2232 | L'.DDatatypeImp x => [(L'.SgiDatatypeImp x, loc)] 2233 | L'.DDatatypeImp x => [(L'.SgiDatatypeImp x, loc)]
2250 (denv, []) => denv 2251 (denv, []) => denv
2251 | _ => raise Fail "sgiBindsD: Sub-constraints remain") 2252 | _ => raise Fail "sgiBindsD: Sub-constraints remain")
2252 | _ => denv 2253 | _ => denv
2253 2254
2254 fun subSgn (env, denv) sgn1 (sgn2 as (_, loc2)) = 2255 fun subSgn (env, denv) sgn1 (sgn2 as (_, loc2)) =
2256 ((*prefaces "subSgn" [("sgn1", p_sgn env sgn1),
2257 ("sgn2", p_sgn env sgn2)];*)
2255 case (#1 (hnormSgn env sgn1), #1 (hnormSgn env sgn2)) of 2258 case (#1 (hnormSgn env sgn1), #1 (hnormSgn env sgn2)) of
2256 (L'.SgnError, _) => () 2259 (L'.SgnError, _) => ()
2257 | (_, L'.SgnError) => () 2260 | (_, L'.SgnError) => ()
2258 2261
2259 | (L'.SgnConst sgis1, L'.SgnConst sgis2) => 2262 | (L'.SgnConst sgis1, L'.SgnConst sgis2) =>
2272 fun seek (env, denv) ls = 2275 fun seek (env, denv) ls =
2273 case ls of 2276 case ls of
2274 [] => (sgnError env (UnmatchedSgi sgi2All); 2277 [] => (sgnError env (UnmatchedSgi sgi2All);
2275 (env, denv)) 2278 (env, denv))
2276 | h :: t => 2279 | h :: t =>
2277 case p h of 2280 case p (env, h) of
2278 NONE => seek (E.sgiBinds env h, sgiBindsD (env, denv) h) t 2281 NONE =>
2282 let
2283 val env = case #1 h of
2284 L'.SgiCon (x, n, k, c) =>
2285 E.pushCNamedAs env x n k (SOME c)
2286 | L'.SgiConAbs (x, n, k) =>
2287 E.pushCNamedAs env x n k NONE
2288 | _ => env
2289 in
2290 seek (E.sgiBinds env h, sgiBindsD (env, denv) h) t
2291 end
2279 | SOME envs => envs 2292 | SOME envs => envs
2280 in 2293 in
2281 seek (env, denv) sgis1 2294 seek (env, denv) sgis1
2282 end 2295 end
2283 in 2296 in
2284 case sgi of 2297 case sgi of
2285 L'.SgiConAbs (x, n2, k2) => 2298 L'.SgiConAbs (x, n2, k2) =>
2286 seek (fn sgi1All as (sgi1, _) => 2299 seek (fn (env, sgi1All as (sgi1, _)) =>
2287 let 2300 let
2288 fun found (x', n1, k1, co1) = 2301 fun found (x', n1, k1, co1) =
2289 if x = x' then 2302 if x = x' then
2290 let 2303 let
2291 val () = unifyKinds k1 k2 2304 val () = unifyKinds k1 k2
2329 SOME c) 2342 SOME c)
2330 | _ => NONE 2343 | _ => NONE
2331 end) 2344 end)
2332 2345
2333 | L'.SgiCon (x, n2, k2, c2) => 2346 | L'.SgiCon (x, n2, k2, c2) =>
2334 seek (fn sgi1All as (sgi1, _) => 2347 seek (fn (env, sgi1All as (sgi1, _)) =>
2335 let 2348 let
2336 fun found (x', n1, k1, c1) = 2349 fun found (x', n1, k1, c1) =
2337 if x = x' then 2350 if x = x' then
2338 let 2351 let
2339 fun good () = 2352 fun good () =
2363 found (x', n1, (L'.KArrow ((L'.KType, loc), (L'.KType, loc)), loc), c1) 2376 found (x', n1, (L'.KArrow ((L'.KType, loc), (L'.KType, loc)), loc), c1)
2364 | _ => NONE 2377 | _ => NONE
2365 end) 2378 end)
2366 2379
2367 | L'.SgiDatatype (x, n2, xs2, xncs2) => 2380 | L'.SgiDatatype (x, n2, xs2, xncs2) =>
2368 seek (fn sgi1All as (sgi1, _) => 2381 seek (fn (env, sgi1All as (sgi1, _)) =>
2369 let 2382 let
2370 fun found (n1, xs1, xncs1) = 2383 fun found (n1, xs1, xncs1) =
2371 let 2384 let
2372 fun mismatched ue = 2385 fun mismatched ue =
2373 (sgnError env (SgiMismatchedDatatypes (sgi1All, sgi2All, ue)); 2386 (sgnError env (SgiMismatchedDatatypes (sgi1All, sgi2All, ue));
2424 NONE 2437 NONE
2425 | _ => NONE 2438 | _ => NONE
2426 end) 2439 end)
2427 2440
2428 | L'.SgiDatatypeImp (x, n2, m12, ms2, s2, xs, _) => 2441 | L'.SgiDatatypeImp (x, n2, m12, ms2, s2, xs, _) =>
2429 seek (fn sgi1All as (sgi1, _) => 2442 seek (fn (env, sgi1All as (sgi1, _)) =>
2430 case sgi1 of 2443 case sgi1 of
2431 L'.SgiDatatypeImp (x', n1, m11, ms1, s1, _, _) => 2444 L'.SgiDatatypeImp (x', n1, m11, ms1, s1, _, _) =>
2432 if x = x' then 2445 if x = x' then
2433 let 2446 let
2434 val k = (L'.KType, loc) 2447 val k = (L'.KType, loc)
2455 NONE 2468 NONE
2456 2469
2457 | _ => NONE) 2470 | _ => NONE)
2458 2471
2459 | L'.SgiVal (x, n2, c2) => 2472 | L'.SgiVal (x, n2, c2) =>
2460 seek (fn sgi1All as (sgi1, _) => 2473 seek (fn (env, sgi1All as (sgi1, _)) =>
2461 case sgi1 of 2474 case sgi1 of
2462 L'.SgiVal (x', n1, c1) => 2475 L'.SgiVal (x', n1, c1) =>
2463 if x = x' then 2476 if x = x' then
2464 ((*prefaces "Pre" [("c1", p_con env c1), 2477 ((*prefaces "Pre" [("c1", p_con env c1),
2465 ("c2", p_con env c2)];*) 2478 ("c2", p_con env c2)];*)
2472 else 2485 else
2473 NONE 2486 NONE
2474 | _ => NONE) 2487 | _ => NONE)
2475 2488
2476 | L'.SgiStr (x, n2, sgn2) => 2489 | L'.SgiStr (x, n2, sgn2) =>
2477 seek (fn sgi1All as (sgi1, _) => 2490 seek (fn (env, sgi1All as (sgi1, _)) =>
2478 case sgi1 of 2491 case sgi1 of
2479 L'.SgiStr (x', n1, sgn1) => 2492 L'.SgiStr (x', n1, sgn1) =>
2480 if x = x' then 2493 if x = x' then
2481 let 2494 let
2482 val () = subSgn (env, denv) sgn1 sgn2 2495 val () = subSgn (env, denv) sgn1 sgn2
2493 else 2506 else
2494 NONE 2507 NONE
2495 | _ => NONE) 2508 | _ => NONE)
2496 2509
2497 | L'.SgiSgn (x, n2, sgn2) => 2510 | L'.SgiSgn (x, n2, sgn2) =>
2498 seek (fn sgi1All as (sgi1, _) => 2511 seek (fn (env, sgi1All as (sgi1, _)) =>
2499 case sgi1 of 2512 case sgi1 of
2500 L'.SgiSgn (x', n1, sgn1) => 2513 L'.SgiSgn (x', n1, sgn1) =>
2501 if x = x' then 2514 if x = x' then
2502 let 2515 let
2503 val () = subSgn (env, denv) sgn1 sgn2 2516 val () = subSgn (env, denv) sgn1 sgn2
2514 else 2527 else
2515 NONE 2528 NONE
2516 | _ => NONE) 2529 | _ => NONE)
2517 2530
2518 | L'.SgiConstraint (c2, d2) => 2531 | L'.SgiConstraint (c2, d2) =>
2519 seek (fn sgi1All as (sgi1, _) => 2532 seek (fn (env, sgi1All as (sgi1, _)) =>
2520 case sgi1 of 2533 case sgi1 of
2521 L'.SgiConstraint (c1, d1) => 2534 L'.SgiConstraint (c1, d1) =>
2522 if consEq (env, denv) (c1, c2) andalso consEq (env, denv) (d1, d2) then 2535 if consEq (env, denv) (c1, c2) andalso consEq (env, denv) (d1, d2) then
2523 let 2536 let
2524 val (denv, gs) = D.assert env denv (c2, d2) 2537 val (denv, gs) = D.assert env denv (c2, d2)
2532 else 2545 else
2533 NONE 2546 NONE
2534 | _ => NONE) 2547 | _ => NONE)
2535 2548
2536 | L'.SgiClassAbs (x, n2) => 2549 | L'.SgiClassAbs (x, n2) =>
2537 seek (fn sgi1All as (sgi1, _) => 2550 seek (fn (env, sgi1All as (sgi1, _)) =>
2538 let 2551 let
2539 fun found (x', n1, co) = 2552 fun found (x', n1, co) =
2540 if x = x' then 2553 if x = x' then
2541 let 2554 let
2542 val k = (L'.KArrow ((L'.KType, loc), (L'.KType, loc)), loc) 2555 val k = (L'.KArrow ((L'.KType, loc), (L'.KType, loc)), loc)
2555 L'.SgiClassAbs (x', n1) => found (x', n1, NONE) 2568 L'.SgiClassAbs (x', n1) => found (x', n1, NONE)
2556 | L'.SgiClass (x', n1, c) => found (x', n1, SOME c) 2569 | L'.SgiClass (x', n1, c) => found (x', n1, SOME c)
2557 | _ => NONE 2570 | _ => NONE
2558 end) 2571 end)
2559 | L'.SgiClass (x, n2, c2) => 2572 | L'.SgiClass (x, n2, c2) =>
2560 seek (fn sgi1All as (sgi1, _) => 2573 seek (fn (env, sgi1All as (sgi1, _)) =>
2561 let 2574 let
2562 val k = (L'.KArrow ((L'.KType, loc), (L'.KType, loc)), loc) 2575 val k = (L'.KArrow ((L'.KType, loc), (L'.KType, loc)), loc)
2563 2576
2564 fun found (x', n1, c1) = 2577 fun found (x', n1, c1) =
2565 if x = x' then 2578 if x = x' then
2604 in 2617 in
2605 subSgn (env, denv) dom2 dom1; 2618 subSgn (env, denv) dom2 dom1;
2606 subSgn (E.pushStrNamedAs env m2 n2 dom2, denv) ran1 ran2 2619 subSgn (E.pushStrNamedAs env m2 n2 dom2, denv) ran1 ran2
2607 end 2620 end
2608 2621
2609 | _ => sgnError env (SgnWrongForm (sgn1, sgn2)) 2622 | _ => sgnError env (SgnWrongForm (sgn1, sgn2)))
2610 2623
2611 2624
2612 fun positive self = 2625 fun positive self =
2613 let 2626 let
2614 open L 2627 open L
2715 | _ => NONE) 2728 | _ => NONE)
2716 | L'.CUnit => SOME (L.CUnit, loc) 2729 | L'.CUnit => SOME (L.CUnit, loc)
2717 2730
2718 | _ => NONE 2731 | _ => NONE
2719 2732
2720 val (needed, constraints, _) = 2733 val (neededC, constraints, neededV, _) =
2721 foldl (fn ((sgi, loc), (needed, constraints, env')) => 2734 foldl (fn ((sgi, loc), (neededC, constraints, neededV, env')) =>
2722 let 2735 let
2723 val (needed, constraints) = 2736 val (needed, constraints, neededV) =
2724 case sgi of 2737 case sgi of
2725 L'.SgiConAbs (x, _, _) => (SS.add (needed, x), constraints) 2738 L'.SgiConAbs (x, _, _) => (SS.add (neededC, x), constraints, neededV)
2726 | L'.SgiConstraint cs => (needed, (env', cs, loc) :: constraints) 2739 | L'.SgiConstraint cs => (neededC, (env', cs, loc) :: constraints, neededV)
2727 | _ => (needed, constraints) 2740
2741 | L'.SgiVal (x, _, t) =>
2742 let
2743 fun default () = (neededC, constraints, neededV)
2744
2745 val t = normClassConstraint env' t
2746 in
2747 case #1 t of
2748 L'.CApp (f, _) =>
2749 if E.isClass env' f then
2750 (neededC, constraints, SS.add (neededV, x))
2751 else
2752 default ()
2753
2754 | _ => default ()
2755 end
2756
2757 | _ => (neededC, constraints, neededV)
2728 in 2758 in
2729 (needed, constraints, E.sgiBinds env' (sgi, loc)) 2759 (needed, constraints, neededV, E.sgiBinds env' (sgi, loc))
2730 end) 2760 end)
2731 (SS.empty, [], env) sgis 2761 (SS.empty, [], SS.empty, env) sgis
2732 2762
2733 val needed = foldl (fn ((d, _), needed) => 2763 val (neededC, neededV) = foldl (fn ((d, _), needed as (neededC, neededV)) =>
2734 case d of 2764 case d of
2735 L.DCon (x, _, _) => (SS.delete (needed, x) 2765 L.DCon (x, _, _) => ((SS.delete (neededC, x), neededV)
2736 handle NotFound => 2766 handle NotFound =>
2737 needed) 2767 needed)
2738 | L.DClass (x, _) => (SS.delete (needed, x) 2768 | L.DClass (x, _) => ((SS.delete (neededC, x), neededV)
2739 handle NotFound => needed) 2769 handle NotFound => needed)
2740 | L.DOpen _ => SS.empty 2770 | L.DVal (x, _, _) => ((neededC, SS.delete (neededV, x))
2741 | _ => needed) 2771 handle NotFound => needed)
2742 needed ds 2772 | L.DOpen _ => (SS.empty, SS.empty)
2743 2773 | _ => needed)
2744 val cds = List.mapPartial (fn (env', (c1, c2), loc) => 2774 (neededC, neededV) ds
2775
2776 val ds' = List.mapPartial (fn (env', (c1, c2), loc) =>
2745 case (decompileCon env' c1, decompileCon env' c2) of 2777 case (decompileCon env' c1, decompileCon env' c2) of
2746 (SOME c1, SOME c2) => 2778 (SOME c1, SOME c2) =>
2747 SOME (L.DConstraint (c1, c2), loc) 2779 SOME (L.DConstraint (c1, c2), loc)
2748 | _ => NONE) constraints 2780 | _ => NONE) constraints
2781
2782 val ds' =
2783 case SS.listItems neededV of
2784 [] => ds'
2785 | xs =>
2786 let
2787 val ewild = (L.EWild, #2 str)
2788 val ds'' = map (fn x => (L.DVal (x, NONE, ewild), #2 str)) xs
2789 in
2790 ds'' @ ds'
2791 end
2792
2793 val ds' =
2794 case SS.listItems neededC of
2795 [] => ds'
2796 | xs =>
2797 let
2798 val kwild = (L.KWild, #2 str)
2799 val cwild = (L.CWild kwild, #2 str)
2800 val ds'' = map (fn x => (L.DCon (x, NONE, cwild), #2 str)) xs
2801 in
2802 ds'' @ ds'
2803 end
2749 in 2804 in
2750 case SS.listItems needed of 2805 (L.StrConst (ds @ ds'), #2 str)
2751 [] => (L.StrConst (ds @ cds), #2 str)
2752 | xs =>
2753 let
2754 val kwild = (L.KWild, #2 str)
2755 val cwild = (L.CWild kwild, #2 str)
2756 val ds' = map (fn x => (L.DCon (x, NONE, cwild), #2 str)) xs
2757 in
2758 (L.StrConst (ds @ ds' @ cds), #2 str)
2759 end
2760 end 2806 end
2761 | _ => str) 2807 | _ => str)
2762 | _ => str 2808 | _ => str
2763 2809
2764 fun elabDecl (dAll as (d, loc), (env, denv, gs : constraint list)) = 2810 fun elabDecl (dAll as (d, loc), (env, denv, gs : constraint list)) =