329 val (nvs', t') = distinct_v (nvs, t); |
329 val (nvs', t') = distinct_v (nvs, t); |
330 val (nvs'', u') = distinct_v (nvs', u); |
330 val (nvs'', u') = distinct_v (nvs', u); |
331 in (nvs'', t' $ u') end |
331 in (nvs'', t' $ u') end |
332 | distinct_v x = x; |
332 | distinct_v x = x; |
333 |
333 |
334 fun compile_match nvs eq_ps out_ps success_p fail_p = |
334 fun is_exhaustive (Var _) = true |
|
335 | is_exhaustive (Const ("Pair", _) $ t $ u) = |
|
336 is_exhaustive t andalso is_exhaustive u |
|
337 | is_exhaustive _ = false; |
|
338 |
|
339 fun compile_match nvs eq_ps out_ps success_p can_fail = |
335 let val eqs = flat (separate [Pretty.str " andalso", Pretty.brk 1] |
340 let val eqs = flat (separate [Pretty.str " andalso", Pretty.brk 1] |
336 (map single (flat (map (mk_eq o snd) nvs) @ eq_ps))); |
341 (map single (flat (map (mk_eq o snd) nvs) @ eq_ps))); |
337 in |
342 in |
338 Pretty.block |
343 Pretty.block |
339 ([Pretty.str "(fn ", mk_tuple out_ps, Pretty.str " =>", Pretty.brk 1] @ |
344 ([Pretty.str "(fn ", mk_tuple out_ps, Pretty.str " =>", Pretty.brk 1] @ |
340 (Pretty.block ((if eqs=[] then [] else Pretty.str "if " :: |
345 (Pretty.block ((if eqs=[] then [] else Pretty.str "if " :: |
341 [Pretty.block eqs, Pretty.brk 1, Pretty.str "then "]) @ |
346 [Pretty.block eqs, Pretty.brk 1, Pretty.str "then "]) @ |
342 (success_p :: |
347 (success_p :: |
343 (if eqs=[] then [] else [Pretty.brk 1, Pretty.str "else ", fail_p]))) :: |
348 (if eqs=[] then [] else [Pretty.brk 1, Pretty.str "else Seq.empty"]))) :: |
344 [Pretty.brk 1, Pretty.str "| _ => ", fail_p, Pretty.str ")"])) |
349 (if can_fail then |
|
350 [Pretty.brk 1, Pretty.str "| _ => Seq.empty)"] |
|
351 else [Pretty.str ")"]))) |
345 end; |
352 end; |
346 |
353 |
347 fun modename thy s (iss, is) = space_implode "__" |
354 fun modename thy s (iss, is) = space_implode "__" |
348 (mk_const_id (sign_of thy) s :: |
355 (mk_const_id (sign_of thy) s :: |
349 map (space_implode "_" o map string_of_int) (mapfilter I iss @ [is])); |
356 map (space_implode "_" o map string_of_int) (mapfilter I iss @ [is])); |
399 (invoke_codegen thy dep false) (gr3, out_ts'''); |
406 (invoke_codegen thy dep false) (gr3, out_ts'''); |
400 val (gr5, eq_ps') = foldl_map compile_eq (gr4, eqs') |
407 val (gr5, eq_ps') = foldl_map compile_eq (gr4, eqs') |
401 in |
408 in |
402 (gr5, compile_match (snd nvs) (eq_ps @ eq_ps') out_ps' |
409 (gr5, compile_match (snd nvs) (eq_ps @ eq_ps') out_ps' |
403 (Pretty.block [Pretty.str "Seq.single", Pretty.brk 1, mk_tuple out_ps]) |
410 (Pretty.block [Pretty.str "Seq.single", Pretty.brk 1, mk_tuple out_ps]) |
404 (Pretty.str "Seq.empty")) |
411 (exists (not o is_exhaustive) out_ts''')) |
405 end |
412 end |
406 | compile_prems out_ts vs names gr ps = |
413 | compile_prems out_ts vs names gr ps = |
407 let |
414 let |
408 val vs' = distinct (flat (vs :: map term_vs out_ts)); |
415 val vs' = distinct (flat (vs :: map term_vs out_ts)); |
409 val Some (p, mode as Some (Mode ((_, js), _))) = |
416 val Some (p, mode as Some (Mode ((_, js), _))) = |
433 val (gr4, rest) = compile_prems out_ts''' vs' (fst nvs) gr3 ps'; |
440 val (gr4, rest) = compile_prems out_ts''' vs' (fst nvs) gr3 ps'; |
434 in |
441 in |
435 (gr4, compile_match (snd nvs) eq_ps out_ps |
442 (gr4, compile_match (snd nvs) eq_ps out_ps |
436 (Pretty.block (ps @ |
443 (Pretty.block (ps @ |
437 [Pretty.str " :->", Pretty.brk 1, rest])) |
444 [Pretty.str " :->", Pretty.brk 1, rest])) |
438 (Pretty.str "Seq.empty")) |
445 (exists (not o is_exhaustive) out_ts'')) |
439 end |
446 end |
440 | Sidecond t => |
447 | Sidecond t => |
441 let |
448 let |
442 val (gr2, side_p) = invoke_codegen thy dep true (gr1, t); |
449 val (gr2, side_p) = invoke_codegen thy dep true (gr1, t); |
443 val (gr3, rest) = compile_prems [] vs' (fst nvs) gr2 ps'; |
450 val (gr3, rest) = compile_prems [] vs' (fst nvs) gr2 ps'; |
444 in |
451 in |
445 (gr3, compile_match (snd nvs) eq_ps out_ps |
452 (gr3, compile_match (snd nvs) eq_ps out_ps |
446 (Pretty.block [Pretty.str "?? ", side_p, |
453 (Pretty.block [Pretty.str "?? ", side_p, |
447 Pretty.str " :->", Pretty.brk 1, rest]) |
454 Pretty.str " :->", Pretty.brk 1, rest]) |
448 (Pretty.str "Seq.empty")) |
455 (exists (not o is_exhaustive) out_ts'')) |
449 end) |
456 end) |
450 end; |
457 end; |
451 |
458 |
452 val (gr', prem_p) = compile_prems in_ts' [] all_vs' gr ps; |
459 val (gr', prem_p) = compile_prems in_ts' [] all_vs' gr ps; |
453 in |
460 in |