Mercurial > urweb
comparison src/reduce.sml @ 909:1d3f60e74ec7
Fixed bug in reduce bind-commutation
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sat, 22 Aug 2009 16:32:31 -0400 |
parents | ed06e25c70ef |
children | 8e540df3294d |
comparison
equal
deleted
inserted
replaced
908:ed06e25c70ef | 909:1d3f60e74ec7 |
---|---|
39 if n = 0 then | 39 if n = 0 then |
40 e | 40 e |
41 else | 41 else |
42 multiLiftExpInExp (n - 1) (E.liftExpInExp 0 e) | 42 multiLiftExpInExp (n - 1) (E.liftExpInExp 0 e) |
43 | 43 |
44 val dangling = | |
45 CoreUtil.Exp.existsB {kind = fn _ => false, | |
46 con = fn _ => false, | |
47 exp = fn (n, e) => | |
48 case e of | |
49 ERel n' => n' >= n | |
50 | _ => false, | |
51 bind = fn (n, b) => | |
52 case b of | |
53 CoreUtil.Exp.RelE _ => n + 1 | |
54 | _ => n} | |
55 | |
44 datatype env_item = | 56 datatype env_item = |
45 UnknownK | 57 UnknownK |
46 | KnownK of kind | 58 | KnownK of kind |
47 | 59 |
48 | UnknownC | 60 | UnknownC |
50 | 62 |
51 | UnknownE | 63 | UnknownE |
52 | KnownE of exp | 64 | KnownE of exp |
53 | 65 |
54 | Lift of int * int * int | 66 | Lift of int * int * int |
67 | |
68 val edepth = foldl (fn (UnknownE, n) => n + 1 | |
69 | (KnownE _, n) => n + 1 | |
70 | (_, n) => n) 0 | |
71 | |
72 val edepth' = foldl (fn (UnknownE, n) => n + 1 | |
73 | (KnownE _, n) => n + 1 | |
74 | (Lift (_, _, n'), n) => n + n' | |
75 | (_, n) => n) 0 | |
55 | 76 |
56 type env = env_item list | 77 type env = env_item list |
57 | 78 |
58 fun ei2s ei = | 79 fun ei2s ei = |
59 case ei of | 80 case ei of |
65 | KnownE _ => "KE" | 86 | KnownE _ => "KE" |
66 | Lift (_, n1, n2) => "(" ^ Int.toString n1 ^ ", " ^ Int.toString n2 ^ ")" | 87 | Lift (_, n1, n2) => "(" ^ Int.toString n1 ^ ", " ^ Int.toString n2 ^ ")" |
67 | 88 |
68 fun e2s env = String.concatWith " " (map ei2s env) | 89 fun e2s env = String.concatWith " " (map ei2s env) |
69 | 90 |
70 val deKnown = List.filter (fn KnownC _ => false | 91 (*val deKnown = List.filter (fn KnownC _ => false |
71 | KnownE _ => false | 92 | KnownE _ => false |
72 | KnownK _ => false | 93 | KnownK _ => false |
73 | _ => true) | 94 | _ => true)*) |
95 | |
96 val deKnown = ListUtil.mapConcat (fn KnownC _ => [] | |
97 | KnownE _ => [] | |
98 | KnownK _ => [] | |
99 | Lift (nk, nc, ne) => List.tabulate (nk, fn _ => UnknownK) | |
100 @ List.tabulate (nc, fn _ => UnknownC) | |
101 @ List.tabulate (ne, fn _ => UnknownE) | |
102 | x => [x]) | |
74 | 103 |
75 fun kindConAndExp (namedC, namedE) = | 104 fun kindConAndExp (namedC, namedE) = |
76 let | 105 let |
77 fun kind env (all as (k, loc)) = | 106 fun kind env (all as (k, loc)) = |
78 case k of | 107 case k of |
220 fun doPart e (this as (x, t), rest) = | 249 fun doPart e (this as (x, t), rest) = |
221 ((x, (EField (e, x, {field = t, rest = (CRecord (k, rest), #2 t)}), #2 t), t), | 250 ((x, (EField (e, x, {field = t, rest = (CRecord (k, rest), #2 t)}), #2 t), t), |
222 this :: rest) | 251 this :: rest) |
223 | 252 |
224 fun exp env (all as (e, loc)) = | 253 fun exp env (all as (e, loc)) = |
225 ((*Print.prefaces "exp" [("e", CorePrint.p_exp CoreEnv.empty all), | 254 let |
226 ("env", Print.PD.string (e2s env))];*) | 255 (*val () = Print.prefaces "exp" [("e", CorePrint.p_exp CoreEnv.empty all), |
227 case e of | 256 ("env", Print.PD.string (e2s env))]*) |
228 EPrim _ => all | 257 (*val () = if dangling (edepth env) all then |
229 | ERel n => | 258 (Print.prefaces "exp" [("e", CorePrint.p_exp CoreEnv.empty all), |
230 let | 259 ("env", Print.PD.string (e2s env))]; |
231 fun find (n', env, nudge, liftK, liftC, liftE) = | 260 raise Fail "!") |
232 case env of | 261 else |
233 [] => raise Fail "Reduce.exp: ERel" | 262 ()*) |
234 | UnknownK :: rest => find (n', rest, nudge, liftK + 1, liftC, liftE) | 263 |
235 | KnownK _ :: rest => find (n', rest, nudge, liftK, liftC, liftE) | 264 val r = case e of |
236 | UnknownC :: rest => find (n', rest, nudge, liftK, liftC + 1, liftE) | 265 EPrim _ => all |
237 | KnownC _ :: rest => find (n', rest, nudge, liftK, liftC, liftE) | 266 | ERel n => |
238 | Lift (liftK', liftC', liftE') :: rest => | 267 let |
239 find (n', rest, nudge + liftE', | 268 fun find (n', env, nudge, liftK, liftC, liftE) = |
240 liftK + liftK', liftC + liftC', liftE + liftE') | 269 case env of |
241 | UnknownE :: rest => | 270 [] => raise Fail ("Reduce.exp: ERel (" ^ ErrorMsg.spanToString loc ^ ")") |
242 if n' = 0 then | 271 | UnknownK :: rest => find (n', rest, nudge, liftK + 1, liftC, liftE) |
243 (ERel (n + nudge), loc) | 272 | KnownK _ :: rest => find (n', rest, nudge, liftK, liftC, liftE) |
244 else | 273 | UnknownC :: rest => find (n', rest, nudge, liftK, liftC + 1, liftE) |
245 find (n' - 1, rest, nudge, liftK, liftC, liftE + 1) | 274 | KnownC _ :: rest => find (n', rest, nudge, liftK, liftC, liftE) |
246 | KnownE e :: rest => | 275 | Lift (liftK', liftC', liftE') :: rest => |
247 if n' = 0 then | 276 find (n', rest, nudge + liftE', |
248 ((*print "SUBSTITUTING\n";*) | 277 liftK + liftK', liftC + liftC', liftE + liftE') |
249 exp (Lift (liftK, liftC, liftE) :: rest) e) | 278 | UnknownE :: rest => |
250 else | 279 if n' = 0 then |
251 find (n' - 1, rest, nudge - 1, liftK, liftC, liftE) | 280 (ERel (n + nudge), loc) |
252 in | 281 else |
253 (*print (Int.toString n ^ ": " ^ e2s env ^ "\n");*) | 282 find (n' - 1, rest, nudge, liftK, liftC, liftE + 1) |
254 find (n, env, 0, 0, 0, 0) | 283 | KnownE e :: rest => |
255 end | 284 if n' = 0 then |
256 | ENamed n => | 285 ((*print "SUBSTITUTING\n";*) |
257 (case IM.find (namedE, n) of | 286 exp (Lift (liftK, liftC, liftE) :: rest) e) |
258 NONE => all | 287 else |
259 | SOME e => e) | 288 find (n' - 1, rest, nudge - 1, liftK, liftC, liftE) |
260 | ECon (dk, pc, cs, eo) => (ECon (dk, patCon pc, | 289 in |
261 map (con env) cs, Option.map (exp env) eo), loc) | 290 (*print (Int.toString n ^ ": " ^ e2s env ^ "\n");*) |
262 | EFfi _ => all | 291 find (n, env, 0, 0, 0, 0) |
263 | EFfiApp (m, f, es) => (EFfiApp (m, f, map (exp env) es), loc) | 292 end |
264 | 293 | ENamed n => |
265 | EApp ( | 294 (case IM.find (namedE, n) of |
266 (EApp | 295 NONE => all |
267 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _), t1), _), t2), _), | 296 | SOME e => e) |
268 _), _), | 297 | ECon (dk, pc, cs, eo) => (ECon (dk, patCon pc, |
269 (EApp ( | 298 map (con env) cs, Option.map (exp env) eo), loc) |
270 (EApp ( | 299 | EFfi _ => all |
271 (ECApp ( | 300 | EFfiApp (m, f, es) => (EFfiApp (m, f, map (exp env) es), loc) |
272 (ECApp ((EFfi ("Basis", "return"), _), _), _), | 301 |
273 _), _), | 302 | EApp ( |
274 _), _), v), _)), _), trans2) => exp env (EApp (trans2, v), loc) | 303 (EApp |
275 | 304 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _), t1), _), t2), _), |
276 (*| EApp ( | 305 _), _), |
277 (EApp | 306 (EApp ( |
278 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _), t1), _), t2), _), | 307 (EApp ( |
279 (EFfi ("Basis", "transaction_monad"), _)), _), | 308 (ECApp ( |
280 (ECase (ed, pes, {disc, ...}), _)), _), | 309 (ECApp ((EFfi ("Basis", "return"), _), _), _), |
281 trans2) => | 310 _), _), |
282 let | 311 _), _), v), _)), _), trans2) => exp env (EApp (trans2, v), loc) |
283 val e' = (EFfi ("Basis", "bind"), loc) | 312 |
284 val e' = (ECApp (e', (CFfi ("Basis", "transaction"), loc)), loc) | 313 (*| EApp ( |
285 val e' = (ECApp (e', t1), loc) | 314 (EApp |
286 val e' = (ECApp (e', t2), loc) | 315 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _), t1), _), t2), _), |
287 val e' = (EApp (e', (EFfi ("Basis", "transaction_monad"), loc)), loc) | 316 (EFfi ("Basis", "transaction_monad"), _)), _), |
288 | 317 (ECase (ed, pes, {disc, ...}), _)), _), |
289 val pes = map (fn (p, e) => | 318 trans2) => |
290 let | 319 let |
291 val e' = (EApp (e', e), loc) | 320 val e' = (EFfi ("Basis", "bind"), loc) |
292 val e' = (EApp (e', | 321 val e' = (ECApp (e', (CFfi ("Basis", "transaction"), loc)), loc) |
293 multiLiftExpInExp (E.patBindsN p) | 322 val e' = (ECApp (e', t1), loc) |
294 trans2), loc) | 323 val e' = (ECApp (e', t2), loc) |
295 val e' = exp env e' | 324 val e' = (EApp (e', (EFfi ("Basis", "transaction_monad"), loc)), loc) |
296 in | 325 |
297 (p, e') | 326 val pes = map (fn (p, e) => |
298 end) pes | 327 let |
299 in | 328 val e' = (EApp (e', e), loc) |
300 (ECase (exp env ed, | 329 val e' = (EApp (e', |
301 pes, | 330 multiLiftExpInExp (E.patBindsN p) |
302 {disc = con env disc, | 331 trans2), loc) |
303 result = (CApp ((CFfi ("Basis", "transaction"), loc), con env t2), loc)}), | 332 val e' = exp env e' |
304 loc) | 333 in |
305 end*) | 334 (p, e') |
306 | 335 end) pes |
307 | EApp ( | 336 in |
308 (EApp | 337 (ECase (exp env ed, |
309 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _), t1), _), t2), _), | 338 pes, |
310 (EFfi ("Basis", "transaction_monad"), _)), _), | 339 {disc = con env disc, |
311 (EServerCall (n, es, ke, dom, ran), _)), _), | 340 result = (CApp ((CFfi ("Basis", "transaction"), loc), con env t2), loc)}), |
312 trans2) => | 341 loc) |
313 let | 342 end*) |
314 val e' = (EFfi ("Basis", "bind"), loc) | 343 |
315 val e' = (ECApp (e', (CFfi ("Basis", "transaction"), loc)), loc) | 344 | EApp ( |
316 val e' = (ECApp (e', dom), loc) | 345 (EApp |
317 val e' = (ECApp (e', t2), loc) | 346 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _), t1), _), t2), _), |
318 val e' = (EApp (e', (EFfi ("Basis", "transaction_monad"), loc)), loc) | 347 (EFfi ("Basis", "transaction_monad"), _)), _), |
319 val e' = (EApp (e', (EApp (E.liftExpInExp 0 ke, (ERel 0, loc)), loc)), loc) | 348 (EServerCall (n, es, ke, dom, ran), _)), _), |
320 val e' = (EApp (e', E.liftExpInExp 0 trans2), loc) | 349 trans2) => |
321 val e' = (EAbs ("x", dom, t2, e'), loc) | 350 let |
322 val e' = (EServerCall (n, es, e', dom, t2), loc) | 351 val e' = (EFfi ("Basis", "bind"), loc) |
323 in | 352 val e' = (ECApp (e', (CFfi ("Basis", "transaction"), loc)), loc) |
324 exp env e' | 353 val e' = (ECApp (e', dom), loc) |
325 end | 354 val e' = (ECApp (e', t2), loc) |
326 | 355 val e' = (EApp (e', (EFfi ("Basis", "transaction_monad"), loc)), loc) |
327 | EApp ( | 356 val e' = (EApp (e', (EApp (E.liftExpInExp 0 ke, (ERel 0, loc)), loc)), loc) |
328 (EApp | 357 val e' = (EApp (e', E.liftExpInExp 0 trans2), loc) |
329 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), _), _), _), _), t3), _), | 358 val e' = (EAbs ("x", dom, t2, e'), loc) |
330 (EFfi ("Basis", "transaction_monad"), _)), _), | 359 val e' = (EServerCall (n, es, e', dom, t2), loc) |
331 (EApp ((EApp | 360 in |
332 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), _), _), _), t1), _), t2), _), | 361 exp env e' |
333 (EFfi ("Basis", "transaction_monad"), _)), _), | 362 end |
334 trans1), _), trans2), _)), _), | 363 |
335 trans3) => | 364 | EApp ( |
336 let | 365 (EApp |
337 val e'' = (EFfi ("Basis", "bind"), loc) | 366 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), loc), mt), _), _), _), t3), _), |
338 val e'' = (ECApp (e'', (CFfi ("Basis", "transaction"), loc)), loc) | 367 me), _), |
339 val e'' = (ECApp (e'', t2), loc) | 368 (EApp ((EApp |
340 val e'' = (ECApp (e'', t3), loc) | 369 ((EApp ((ECApp ((ECApp ((ECApp ((EFfi ("Basis", "bind"), _), _), _), t1), _), t2), _), |
341 val e'' = (EApp (e'', (EFfi ("Basis", "transaction_monad"), loc)), loc) | 370 _), _), |
342 val e'' = (EApp (e'', (EApp (E.liftExpInExp 0 trans2, (ERel 0, loc)), loc)), loc) | 371 trans1), _), trans2), _)), _), |
343 val e'' = (EApp (e'', E.liftExpInExp 0 trans3), loc) | 372 trans3) => |
344 val e'' = (EAbs ("x", t1, (CApp ((CFfi ("Basis", "transaction"), loc), t3), loc), e''), loc) | 373 let |
345 | 374 val e'' = (EFfi ("Basis", "bind"), loc) |
346 val e' = (EFfi ("Basis", "bind"), loc) | 375 val e'' = (ECApp (e'', mt), loc) |
347 val e' = (ECApp (e', (CFfi ("Basis", "transaction"), loc)), loc) | 376 val e'' = (ECApp (e'', t2), loc) |
348 val e' = (ECApp (e', t1), loc) | 377 val e'' = (ECApp (e'', t3), loc) |
349 val e' = (ECApp (e', t3), loc) | 378 val e'' = (EApp (e'', me), loc) |
350 val e' = (EApp (e', (EFfi ("Basis", "transaction_monad"), loc)), loc) | 379 val e'' = (EApp (e'', (EApp (E.liftExpInExp 0 trans2, (ERel 0, loc)), loc)), loc) |
351 val e' = (EApp (e', trans1), loc) | 380 val e'' = (EApp (e'', E.liftExpInExp 0 trans3), loc) |
352 val e' = (EApp (e', e''), loc) | 381 val e'' = (EAbs ("xb", t1, (CApp (mt, t3), loc), e''), loc) |
353 in | 382 |
354 exp env e' | 383 val e' = (EFfi ("Basis", "bind"), loc) |
355 end | 384 val e' = (ECApp (e', mt), loc) |
356 | 385 val e' = (ECApp (e', t1), loc) |
357 | EApp (e1, e2) => | 386 val e' = (ECApp (e', t3), loc) |
358 let | 387 val e' = (EApp (e', me), loc) |
359 val e1 = exp env e1 | 388 val e' = (EApp (e', trans1), loc) |
360 val e2 = exp env e2 | 389 val e' = (EApp (e', e''), loc) |
361 in | 390 (*val () = print "Before\n"*) |
362 case #1 e1 of | 391 val ee' = exp env e' |
363 EAbs (_, _, _, b) => exp (KnownE e2 :: deKnown env) b | 392 (*val () = print "After\n"*) |
364 | _ => (EApp (e1, e2), loc) | 393 in |
365 end | 394 (*Print.prefaces "Commute" [("Pre", CorePrint.p_exp CoreEnv.empty (e, loc)), |
366 | 395 ("Mid", CorePrint.p_exp CoreEnv.empty e'), |
367 | EAbs (x, dom, ran, e) => (EAbs (x, con env dom, con env ran, exp (UnknownE :: env) e), loc) | 396 ("env", Print.PD.string (e2s env)), |
368 | 397 ("Post", CorePrint.p_exp CoreEnv.empty ee')];*) |
369 | ECApp (e, c) => | 398 ee' |
370 let | 399 end |
371 val e = exp env e | 400 |
372 val c = con env c | 401 | EApp (e1, e2) => |
373 in | 402 let |
374 case #1 e of | 403 val e1 = exp env e1 |
375 ECAbs (_, _, b) => exp (KnownC c :: deKnown env) b | 404 val e2 = exp env e2 |
376 | _ => (ECApp (e, c), loc) | 405 in |
377 end | 406 case #1 e1 of |
378 | 407 EAbs (_, _, _, b) => |
379 | ECAbs (x, k, e) => (ECAbs (x, kind env k, exp (UnknownC :: env) e), loc) | 408 ((*Print.preface ("Body", CorePrint.p_exp CoreEnv.empty b);*) |
380 | 409 exp (KnownE e2 :: deKnown env) b) |
381 | EKApp (e, k) => | 410 | _ => (EApp (e1, e2), loc) |
382 let | 411 end |
383 val e = exp env e | 412 |
384 in | 413 | EAbs (x, dom, ran, e) => (EAbs (x, con env dom, con env ran, exp (UnknownE :: env) e), loc) |
385 case #1 e of | 414 |
386 EKAbs (_, b) => exp (KnownK k :: deKnown env) b | 415 | ECApp (e, c) => |
387 | _ => (EKApp (e, kind env k), loc) | 416 let |
388 end | 417 val e = exp env e |
389 | 418 val c = con env c |
390 | EKAbs (x, e) => (EKAbs (x, exp (UnknownK :: env) e), loc) | 419 in |
391 | 420 case #1 e of |
392 | ERecord xcs => (ERecord (map (fn (x, e, t) => (con env x, exp env e, con env t)) xcs), loc) | 421 ECAbs (_, _, b) => exp (KnownC c :: deKnown env) b |
393 | EField (e, c, {field, rest}) => | 422 | _ => (ECApp (e, c), loc) |
394 let | 423 end |
395 val e = exp env e | 424 |
396 val c = con env c | 425 | ECAbs (x, k, e) => (ECAbs (x, kind env k, exp (UnknownC :: env) e), loc) |
397 | 426 |
398 fun default () = (EField (e, c, {field = con env field, rest = con env rest}), loc) | 427 | EKApp (e, k) => |
399 in | 428 let |
400 case (#1 e, #1 c) of | 429 val e = exp env e |
401 (ERecord xcs, CName x) => | 430 in |
402 (case List.find (fn ((CName x', _), _, _) => x' = x | _ => false) xcs of | 431 case #1 e of |
403 NONE => default () | 432 EKAbs (_, b) => exp (KnownK k :: deKnown env) b |
404 | SOME (_, e, _) => e) | 433 | _ => (EKApp (e, kind env k), loc) |
405 | _ => default () | 434 end |
406 end | 435 |
407 | 436 | EKAbs (x, e) => (EKAbs (x, exp (UnknownK :: env) e), loc) |
408 | EConcat (e1, c1, e2, c2) => | 437 |
409 let | 438 | ERecord xcs => (ERecord (map (fn (x, e, t) => (con env x, exp env e, con env t)) xcs), loc) |
410 val e1 = exp env e1 | 439 | EField (e, c, {field, rest}) => |
411 val e2 = exp env e2 | 440 let |
412 in | 441 val e = exp env e |
413 case (#1 e1, #1 e2) of | 442 val c = con env c |
414 (ERecord xes1, ERecord xes2) => (ERecord (xes1 @ xes2), loc) | 443 |
415 | _ => | 444 fun default () = (EField (e, c, {field = con env field, rest = con env rest}), loc) |
416 let | 445 in |
417 val c1 = con env c1 | 446 case (#1 e, #1 c) of |
418 val c2 = con env c2 | 447 (ERecord xcs, CName x) => |
419 in | 448 (case List.find (fn ((CName x', _), _, _) => x' = x | _ => false) xcs of |
420 case (#1 c1, #1 c2) of | 449 NONE => default () |
421 (CRecord (k, xcs1), CRecord (_, xcs2)) => | 450 | SOME (_, e, _) => e) |
422 let | 451 | _ => default () |
423 val (xes1, rest) = ListUtil.foldlMap (doPart e1) [] xcs1 | 452 end |
424 val (xes2, _) = ListUtil.foldlMap (doPart e2) rest xcs2 | 453 |
425 in | 454 | EConcat (e1, c1, e2, c2) => |
426 exp (deKnown env) (ERecord (xes1 @ xes2), loc) | 455 let |
427 end | 456 val e1 = exp env e1 |
428 | _ => (EConcat (e1, c1, e2, c2), loc) | 457 val e2 = exp env e2 |
429 end | 458 in |
430 end | 459 case (#1 e1, #1 e2) of |
431 | 460 (ERecord xes1, ERecord xes2) => (ERecord (xes1 @ xes2), loc) |
432 | ECut (e, c, {field, rest}) => | 461 | _ => |
433 let | 462 let |
434 val e = exp env e | 463 val c1 = con env c1 |
435 val c = con env c | 464 val c2 = con env c2 |
436 | 465 in |
437 fun default () = | 466 case (#1 c1, #1 c2) of |
438 let | 467 (CRecord (k, xcs1), CRecord (_, xcs2)) => |
439 val rest = con env rest | 468 let |
440 in | 469 val (xes1, rest) = ListUtil.foldlMap (doPart e1) [] xcs1 |
441 case #1 rest of | 470 val (xes2, _) = ListUtil.foldlMap (doPart e2) rest xcs2 |
442 CRecord (k, xcs) => | 471 in |
443 let | 472 exp (deKnown env) (ERecord (xes1 @ xes2), loc) |
444 val (xes, _) = ListUtil.foldlMap (doPart e) [] xcs | 473 end |
445 in | 474 | _ => (EConcat (e1, c1, e2, c2), loc) |
446 exp (deKnown env) (ERecord xes, loc) | 475 end |
447 end | 476 end |
448 | _ => (ECut (e, c, {field = con env field, rest = rest}), loc) | 477 |
449 end | 478 | ECut (e, c, {field, rest}) => |
450 in | 479 let |
451 case (#1 e, #1 c) of | 480 val e = exp env e |
452 (ERecord xes, CName x) => | 481 val c = con env c |
453 if List.all (fn ((CName _, _), _, _) => true | _ => false) xes then | 482 |
454 (ERecord (List.filter (fn ((CName x', _), _, _) => x' <> x | 483 fun default () = |
455 | _ => raise Fail "Reduce: ECut") xes), loc) | 484 let |
456 else | 485 val rest = con env rest |
457 default () | 486 in |
458 | _ => default () | 487 case #1 rest of |
459 end | 488 CRecord (k, xcs) => |
460 | 489 let |
461 | ECutMulti (e, c, {rest}) => | 490 val (xes, _) = ListUtil.foldlMap (doPart e) [] xcs |
462 let | 491 in |
463 val e = exp env e | 492 exp (deKnown env) (ERecord xes, loc) |
464 val c = con env c | 493 end |
465 | 494 | _ => (ECut (e, c, {field = con env field, rest = rest}), loc) |
466 fun default () = | 495 end |
467 let | 496 in |
468 val rest = con env rest | 497 case (#1 e, #1 c) of |
469 in | 498 (ERecord xes, CName x) => |
470 case #1 rest of | 499 if List.all (fn ((CName _, _), _, _) => true | _ => false) xes then |
471 CRecord (k, xcs) => | 500 (ERecord (List.filter (fn ((CName x', _), _, _) => x' <> x |
472 let | 501 | _ => raise Fail "Reduce: ECut") xes), loc) |
473 val (xes, _) = ListUtil.foldlMap (doPart e) [] xcs | 502 else |
474 in | 503 default () |
475 exp (deKnown env) (ERecord xes, loc) | 504 | _ => default () |
476 end | 505 end |
477 | _ => (ECutMulti (e, c, {rest = rest}), loc) | 506 |
478 end | 507 | ECutMulti (e, c, {rest}) => |
479 in | 508 let |
480 case (#1 e, #1 c) of | 509 val e = exp env e |
481 (ERecord xes, CRecord (_, xcs)) => | 510 val c = con env c |
482 if List.all (fn ((CName _, _), _, _) => true | _ => false) xes | 511 |
483 andalso List.all (fn ((CName _, _), _) => true | _ => false) xcs then | 512 fun default () = |
484 (ERecord (List.filter (fn ((CName x', _), _, _) => | 513 let |
485 List.all (fn ((CName x, _), _) => x' <> x | 514 val rest = con env rest |
486 | _ => raise Fail "Reduce: ECutMulti [1]") xcs | 515 in |
487 | _ => raise Fail "Reduce: ECutMulti [2]") xes), loc) | 516 case #1 rest of |
488 else | 517 CRecord (k, xcs) => |
489 default () | 518 let |
490 | _ => default () | 519 val (xes, _) = ListUtil.foldlMap (doPart e) [] xcs |
491 end | 520 in |
492 | 521 exp (deKnown env) (ERecord xes, loc) |
493 | ECase (_, [((PRecord [], _), e)], _) => exp env e | 522 end |
494 | ECase (_, [((PWild, _), e)], _) => exp env e | 523 | _ => (ECutMulti (e, c, {rest = rest}), loc) |
495 | 524 end |
496 | ECase (e, pes, {disc, result}) => | 525 in |
497 let | 526 case (#1 e, #1 c) of |
498 fun patBinds (p, _) = | 527 (ERecord xes, CRecord (_, xcs)) => |
499 case p of | 528 if List.all (fn ((CName _, _), _, _) => true | _ => false) xes |
500 PWild => 0 | 529 andalso List.all (fn ((CName _, _), _) => true | _ => false) xcs then |
501 | PVar _ => 1 | 530 (ERecord (List.filter (fn ((CName x', _), _, _) => |
502 | PPrim _ => 0 | 531 List.all (fn ((CName x, _), _) => x' <> x |
503 | PCon (_, _, _, NONE) => 0 | 532 | _ => raise Fail "Reduce: ECutMulti [1]") xcs |
504 | PCon (_, _, _, SOME p) => patBinds p | 533 | _ => raise Fail "Reduce: ECutMulti [2]") xes), loc) |
505 | PRecord xpts => foldl (fn ((_, p, _), n) => n + patBinds p) 0 xpts | 534 else |
506 | 535 default () |
507 fun pat (all as (p, loc)) = | 536 | _ => default () |
508 case p of | 537 end |
509 PWild => all | 538 |
510 | PVar (x, t) => (PVar (x, con env t), loc) | 539 | ECase (_, [((PRecord [], _), e)], _) => exp env e |
511 | PPrim _ => all | 540 | ECase (_, [((PWild, _), e)], _) => exp env e |
512 | PCon (dk, pc, cs, po) => | 541 |
513 (PCon (dk, patCon pc, map (con env) cs, Option.map pat po), loc) | 542 | ECase (e, pes, {disc, result}) => |
514 | PRecord xpts => (PRecord (map (fn (x, p, t) => (x, pat p, con env t)) xpts), loc) | 543 let |
515 in | 544 fun patBinds (p, _) = |
516 (ECase (exp env e, | 545 case p of |
517 map (fn (p, e) => (pat p, | 546 PWild => 0 |
518 exp (List.tabulate (patBinds p, fn _ => UnknownE) @ env) e)) | 547 | PVar _ => 1 |
519 pes, {disc = con env disc, result = con env result}), loc) | 548 | PPrim _ => 0 |
520 end | 549 | PCon (_, _, _, NONE) => 0 |
521 | 550 | PCon (_, _, _, SOME p) => patBinds p |
522 | EWrite e => (EWrite (exp env e), loc) | 551 | PRecord xpts => foldl (fn ((_, p, _), n) => n + patBinds p) 0 xpts |
523 | EClosure (n, es) => (EClosure (n, map (exp env) es), loc) | 552 |
524 | 553 fun pat (all as (p, loc)) = |
525 | ELet (x, t, e1, e2) => (ELet (x, con env t, exp env e1, exp (UnknownE :: env) e2), loc) | 554 case p of |
526 | 555 PWild => all |
527 | EServerCall (n, es, e, t1, t2) => (EServerCall (n, map (exp env) es, exp env e, | 556 | PVar (x, t) => (PVar (x, con env t), loc) |
528 con env t1, con env t2), loc)) | 557 | PPrim _ => all |
558 | PCon (dk, pc, cs, po) => | |
559 (PCon (dk, patCon pc, map (con env) cs, Option.map pat po), loc) | |
560 | PRecord xpts => (PRecord (map (fn (x, p, t) => (x, pat p, con env t)) xpts), loc) | |
561 in | |
562 (ECase (exp env e, | |
563 map (fn (p, e) => (pat p, | |
564 exp (List.tabulate (patBinds p, fn _ => UnknownE) @ env) e)) | |
565 pes, {disc = con env disc, result = con env result}), loc) | |
566 end | |
567 | |
568 | EWrite e => (EWrite (exp env e), loc) | |
569 | EClosure (n, es) => (EClosure (n, map (exp env) es), loc) | |
570 | |
571 | ELet (x, t, e1, e2) => (ELet (x, con env t, exp env e1, exp (UnknownE :: env) e2), loc) | |
572 | |
573 | EServerCall (n, es, e, t1, t2) => (EServerCall (n, map (exp env) es, exp env e, | |
574 con env t1, con env t2), loc) | |
575 in | |
576 (*if dangling (edepth' (deKnown env)) r then | |
577 (Print.prefaces "exp" [("e", CorePrint.p_exp CoreEnv.empty all), | |
578 ("r", CorePrint.p_exp CoreEnv.empty r)]; | |
579 raise Fail "!!") | |
580 else | |
581 ();*) | |
582 r | |
583 end | |
529 in | 584 in |
530 {kind = kind, con = con, exp = exp} | 585 {kind = kind, con = con, exp = exp} |
531 end | 586 end |
532 | 587 |
533 fun kind namedC env k = #kind (kindConAndExp (namedC, IM.empty)) env k | 588 fun kind namedC env k = #kind (kindConAndExp (namedC, IM.empty)) env k |