310 |
306 |
311 val fp_fold_fun_Ts = fst (split_last (binder_types (fastype_of any_fp_fold))); |
307 val fp_fold_fun_Ts = fst (split_last (binder_types (fastype_of any_fp_fold))); |
312 val fp_rec_fun_Ts = fst (split_last (binder_types (fastype_of any_fp_rec))); |
308 val fp_rec_fun_Ts = fst (split_last (binder_types (fastype_of any_fp_rec))); |
313 |
309 |
314 val (((fold_only as (gss, _, _), rec_only as (hss, _, _)), |
310 val (((fold_only as (gss, _, _), rec_only as (hss, _, _)), |
315 (zs, cs, cpss, unfold_only as ((pgss, crgsss), _), corec_only as ((phss, cshsss), _))), |
311 (cs, cpss, unfold_only as ((pgss, crssss, cgssss), (_, g_Tsss, _)), |
316 names_lthy0) = |
312 corec_only as ((phss, csssss, chssss), (_, h_Tsss, _)))), names_lthy0) = |
317 if lfp then |
313 if lfp then |
318 let |
314 let |
319 val y_Tsss = |
315 val y_Tsss = |
320 map3 (fn n => fn ms => map2 dest_tupleT ms o dest_sumTN_balanced n o domain_type) |
316 map3 (fn n => fn ms => map2 dest_tupleT ms o dest_sumTN_balanced n o domain_type) |
321 ns mss fp_fold_fun_Ts; |
317 ns mss fp_fold_fun_Ts; |
342 |
338 |
343 val hss = map2 (map2 retype_free) h_Tss gss; |
339 val hss = map2 (map2 retype_free) h_Tss gss; |
344 val zsss = map2 (map2 (map2 retype_free)) z_Tsss ysss; |
340 val zsss = map2 (map2 (map2 retype_free)) z_Tsss ysss; |
345 in |
341 in |
346 ((((gss, g_Tss, ysss), (hss, h_Tss, zsss)), |
342 ((((gss, g_Tss, ysss), (hss, h_Tss, zsss)), |
347 ([], [], [], (([], []), ([], [])), (([], []), ([], [])))), lthy) |
343 ([], [], (([], [], []), ([], [], [])), (([], [], []), ([], [], [])))), lthy) |
348 end |
344 end |
349 else |
345 else |
350 let |
346 let |
351 (*avoid "'a itself" arguments in coiterators and corecursors*) |
347 (*avoid "'a itself" arguments in coiterators and corecursors*) |
352 val mss' = map (fn [0] => [1] | ms => ms) mss; |
348 val mss' = map (fn [0] => [1] | ms => ms) mss; |
371 val pf_Tss = map3 flat_preds_predsss_gettersss p_Tss q_Tssss f_Tssss; |
367 val pf_Tss = map3 flat_preds_predsss_gettersss p_Tss q_Tssss f_Tssss; |
372 in (q_Tssss, f_sum_prod_Ts, f_Tsss, f_Tssss, pf_Tss) end; |
368 in (q_Tssss, f_sum_prod_Ts, f_Tsss, f_Tssss, pf_Tss) end; |
373 |
369 |
374 val (r_Tssss, g_sum_prod_Ts, g_Tsss, g_Tssss, pg_Tss) = mk_types single fp_fold_fun_Ts; |
370 val (r_Tssss, g_sum_prod_Ts, g_Tsss, g_Tssss, pg_Tss) = mk_types single fp_fold_fun_Ts; |
375 |
371 |
376 val ((((Free (z, _), cs), pss), gssss), lthy) = |
372 val (((cs, pss), gssss), lthy) = |
377 lthy |
373 lthy |
378 |> yield_singleton (mk_Frees "z") dummyT |
374 |> mk_Frees "a" Cs |
379 ||>> mk_Frees "a" Cs |
|
380 ||>> mk_Freess "p" p_Tss |
375 ||>> mk_Freess "p" p_Tss |
381 ||>> mk_Freessss "g" g_Tssss; |
376 ||>> mk_Freessss "g" g_Tssss; |
382 val rssss = map (map (map (fn [] => []))) r_Tssss; |
377 val rssss = map (map (map (fn [] => []))) r_Tssss; |
383 |
378 |
384 fun proj_corecT proj (Type (s as @{type_name sum}, Ts as [T, U])) = |
379 fun proj_corecT proj (Type (s as @{type_name sum}, Ts as [T, U])) = |
399 ||>> mk_Freessss "h" (map (map (map tl)) h_Tssss); |
394 ||>> mk_Freessss "h" (map (map (map tl)) h_Tssss); |
400 val hssss = map2 (map2 (map2 cons)) hssss_hd hssss_tl; |
395 val hssss = map2 (map2 (map2 cons)) hssss_hd hssss_tl; |
401 |
396 |
402 val cpss = map2 (map o rapp) cs pss; |
397 val cpss = map2 (map o rapp) cs pss; |
403 |
398 |
404 fun build_sum_inj mk_inj (T, U) = |
399 fun mk_terms qssss fssss = |
405 if T = U then |
|
406 id_const T |
|
407 else |
|
408 (case (T, U) of |
|
409 (Type (s, _), Type (s', _)) => |
|
410 if s = s' then build_map (build_sum_inj mk_inj) T U |
|
411 else uncurry mk_inj (dest_sumT U) |
|
412 | _ => uncurry mk_inj (dest_sumT U)); |
|
413 |
|
414 fun build_dtor_corec_arg _ [] [cf] = cf |
|
415 | build_dtor_corec_arg T [cq] [cf, cf'] = |
|
416 mk_If cq (build_sum_inj Inl_const (fastype_of cf, T) $ cf) |
|
417 (build_sum_inj Inr_const (fastype_of cf', T) $ cf') |
|
418 |
|
419 fun mk_terms f_Tsss qssss fssss = |
|
420 let |
400 let |
421 val pfss = map3 flat_preds_predsss_gettersss pss qssss fssss; |
401 val pfss = map3 flat_preds_predsss_gettersss pss qssss fssss; |
422 val cqssss = map2 (map o map o map o rapp) cs qssss; |
402 val cqssss = map2 (map o map o map o rapp) cs qssss; |
423 val cfssss = map2 (map o map o map o rapp) cs fssss; |
403 val cfssss = map2 (map o map o map o rapp) cs fssss; |
424 val cqfsss = map3 (map3 (map3 build_dtor_corec_arg)) f_Tsss cqssss cfssss; |
404 in (pfss, cqssss, cfssss) end; |
425 in (pfss, cqfsss) end; |
|
426 in |
405 in |
427 (((([], [], []), ([], [], [])), |
406 (((([], [], []), ([], [], [])), |
428 ([z], cs, cpss, (mk_terms g_Tsss rssss gssss, (g_sum_prod_Ts, pg_Tss)), |
407 (cs, cpss, (mk_terms rssss gssss, (g_sum_prod_Ts, g_Tsss, pg_Tss)), |
429 (mk_terms h_Tsss sssss hssss, (h_sum_prod_Ts, ph_Tss)))), lthy) |
408 (mk_terms sssss hssss, (h_sum_prod_Ts, h_Tsss, ph_Tss)))), lthy) |
430 end; |
409 end; |
431 |
410 |
432 fun define_ctrs_case_for_type (((((((((((((((((((((((((fp_bnf, fp_b), fpT), C), ctor), dtor), |
411 fun define_ctrs_case_for_type (((((((((((((((((((((((((fp_bnf, fp_b), fpT), C), ctor), dtor), |
433 fp_fold), fp_rec), ctor_dtor), dtor_ctor), ctor_inject), pre_map_def), pre_set_defs), |
412 fp_fold), fp_rec), ctor_dtor), dtor_ctor), ctor_inject), pre_map_def), pre_set_defs), |
434 pre_rel_def), fp_map_thm), fp_set_thms), fp_rel_thm), n), ks), ms), ctr_bindings), |
413 pre_rel_def), fp_map_thm), fp_set_thms), fp_rel_thm), n), ks), ms), ctr_bindings), |
666 |
645 |
667 fun define_unfold_corec no_defs_lthy = |
646 fun define_unfold_corec no_defs_lthy = |
668 let |
647 let |
669 val B_to_fpT = C --> fpT; |
648 val B_to_fpT = C --> fpT; |
670 |
649 |
|
650 fun build_sum_inj mk_inj (T, U) = |
|
651 if T = U then |
|
652 id_const T |
|
653 else |
|
654 (case (T, U) of |
|
655 (Type (s, _), Type (s', _)) => |
|
656 if s = s' then build_map (build_sum_inj mk_inj) T U |
|
657 else uncurry mk_inj (dest_sumT U) |
|
658 | _ => uncurry mk_inj (dest_sumT U)); |
|
659 |
|
660 fun build_dtor_corec_like_arg _ [] [cf] = cf |
|
661 | build_dtor_corec_like_arg T [cq] [cf, cf'] = |
|
662 mk_If cq (build_sum_inj Inl_const (fastype_of cf, T) $ cf) |
|
663 (build_sum_inj Inr_const (fastype_of cf', T) $ cf') |
|
664 |
|
665 val crgsss = map3 (map3 (map3 build_dtor_corec_like_arg)) g_Tsss crssss cgssss; |
|
666 val cshsss = map3 (map3 (map3 build_dtor_corec_like_arg)) h_Tsss csssss chssss; |
|
667 |
671 fun mk_preds_getterss_join c n cps sum_prod_T cqfss = |
668 fun mk_preds_getterss_join c n cps sum_prod_T cqfss = |
672 Term.lambda c (mk_IfN sum_prod_T cps |
669 Term.lambda c (mk_IfN sum_prod_T cps |
673 (map2 (mk_InN_balanced sum_prod_T n) (map HOLogic.mk_tuple cqfss) (1 upto n))); |
670 (map2 (mk_InN_balanced sum_prod_T n) (map HOLogic.mk_tuple cqfss) (1 upto n))); |
674 |
671 |
675 fun generate_corec_like (suf, fp_rec_like, ((pfss, cqfsss), (f_sum_prod_Ts, |
672 fun generate_corec_like (suf, fp_rec_like, (cqfsss, ((pfss, _, _), (f_sum_prod_Ts, _, |
676 pf_Tss))) = |
673 pf_Tss)))) = |
677 let |
674 let |
678 val res_T = fold_rev (curry (op --->)) pf_Tss B_to_fpT; |
675 val res_T = fold_rev (curry (op --->)) pf_Tss B_to_fpT; |
679 val binding = qualify false fp_b_name (Binding.suffix_name ("_" ^ suf) fp_b); |
676 val binding = qualify false fp_b_name (Binding.suffix_name ("_" ^ suf) fp_b); |
680 val spec = |
677 val spec = |
681 mk_Trueprop_eq (lists_bmoc pfss (Free (Binding.name_of binding, res_T)), |
678 mk_Trueprop_eq (lists_bmoc pfss (Free (Binding.name_of binding, res_T)), |
682 Term.list_comb (fp_rec_like, |
679 Term.list_comb (fp_rec_like, |
683 map5 mk_preds_getterss_join cs ns cpss f_sum_prod_Ts cqfsss)); |
680 map5 mk_preds_getterss_join cs ns cpss f_sum_prod_Ts cqfsss)); |
684 in (binding, spec) end; |
681 in (binding, spec) end; |
685 |
682 |
686 val corec_like_infos = |
683 val corec_like_infos = |
687 [(unfoldN, fp_fold, unfold_only), |
684 [(unfoldN, fp_fold, (crgsss, unfold_only)), |
688 (corecN, fp_rec, corec_only)]; |
685 (corecN, fp_rec, (cshsss, corec_only))]; |
689 |
686 |
690 val (bindings, specs) = map generate_corec_like corec_like_infos |> split_list; |
687 val (bindings, specs) = map generate_corec_like corec_like_infos |> split_list; |
691 |
688 |
692 val ((csts, defs), (lthy', lthy)) = no_defs_lthy |
689 val ((csts, defs), (lthy', lthy)) = no_defs_lthy |
693 |> apfst split_list o fold_map2 (fn b => fn spec => |
690 |> apfst split_list o fold_map2 (fn b => fn spec => |
972 (postproc nn (prove fp_induct goal), postproc nn (prove fp_strong_induct strong_goal)) |
968 (postproc nn (prove fp_induct goal), postproc nn (prove fp_strong_induct strong_goal)) |
973 end; |
969 end; |
974 |
970 |
975 fun mk_maybe_not pos = not pos ? HOLogic.mk_not; |
971 fun mk_maybe_not pos = not pos ? HOLogic.mk_not; |
976 |
972 |
977 val z = the_single zs; |
|
978 val gunfolds = map (lists_bmoc pgss) unfolds; |
973 val gunfolds = map (lists_bmoc pgss) unfolds; |
979 val hcorecs = map (lists_bmoc phss) corecs; |
974 val hcorecs = map (lists_bmoc phss) corecs; |
980 |
975 |
981 val (unfold_thmss, corec_thmss, safe_unfold_thmss, safe_corec_thmss) = |
976 val (unfold_thmss, corec_thmss, safe_unfold_thmss, safe_corec_thmss) = |
982 let |
977 let |
983 fun mk_goal pfss c cps fcorec_like n k ctr m cfs' = |
978 fun mk_goal pfss c cps fcorec_like n k ctr m cfs' = |
984 fold_rev (fold_rev Logic.all) ([c] :: pfss) |
979 fold_rev (fold_rev Logic.all) ([c] :: pfss) |
985 (Logic.list_implies (seq_conds (HOLogic.mk_Trueprop oo mk_maybe_not) n k cps, |
980 (Logic.list_implies (seq_conds (HOLogic.mk_Trueprop oo mk_maybe_not) n k cps, |
986 mk_Trueprop_eq (fcorec_like $ c, Term.list_comb (ctr, take m cfs')))); |
981 mk_Trueprop_eq (fcorec_like $ c, Term.list_comb (ctr, take m cfs')))); |
987 |
982 |
988 fun build_corec_like fcorec_likes maybe_tack (T, U) = |
983 fun build_corec_like fcorec_likes (T, U) = |
989 if T = U then |
984 if T = U then |
990 id_const T |
985 id_const T |
991 else |
986 else |
992 (case find_index (curry (op =) U) fpTs of |
987 (case find_index (curry (op =) U) fpTs of |
993 ~1 => build_map (build_corec_like fcorec_likes maybe_tack) T U |
988 ~1 => build_map (build_corec_like fcorec_likes) T U |
994 | kk => maybe_tack (nth cs kk, nth us kk) (nth fcorec_likes kk)); |
989 | kk => nth fcorec_likes kk); |
995 |
990 |
996 fun mk_U maybe_mk_sumT = |
991 val mk_U = typ_subst (map2 pair Cs fpTs); |
997 typ_subst (map2 (fn C => fn fpT => (maybe_mk_sumT fpT C, fpT)) Cs fpTs); |
992 |
998 |
993 fun intr_corec_likes fcorec_likes [] [cf] = |
999 fun intr_corec_likes fcorec_likes maybe_mk_sumT maybe_tack cqf = |
994 let val T = fastype_of cf in |
1000 let val T = fastype_of cqf in |
995 if exists_Cs_subtype T then build_corec_like fcorec_likes (T, mk_U T) $ cf else cf |
1001 if exists_Cs_subtype T then |
996 end |
1002 build_corec_like fcorec_likes maybe_tack (T, mk_U maybe_mk_sumT T) $ cqf |
997 | intr_corec_likes fcorec_likes [cq] [cf, cf'] = |
1003 else |
998 mk_If cq (intr_corec_likes fcorec_likes [] [cf]) |
1004 cqf |
999 (intr_corec_likes fcorec_likes [] [cf']); |
|
1000 |
|
1001 val crgsss = map2 (map2 (map2 (intr_corec_likes gunfolds))) crssss cgssss; |
|
1002 val cshsss = map2 (map2 (map2 (intr_corec_likes hcorecs))) csssss chssss; |
|
1003 |
|
1004 val unfold_goalss = |
|
1005 map8 (map4 oooo mk_goal pgss) cs cpss gunfolds ns kss ctrss mss crgsss; |
|
1006 val corec_goalss = |
|
1007 map8 (map4 oooo mk_goal phss) cs cpss hcorecs ns kss ctrss mss cshsss; |
|
1008 |
|
1009 fun mk_map_if_distrib bnf = |
|
1010 let |
|
1011 val mapx = map_of_bnf bnf; |
|
1012 val live = live_of_bnf bnf; |
|
1013 val ((Ts, T), U) = strip_typeN (live + 1) (fastype_of mapx) |>> split_last; |
|
1014 val fs = Variable.variant_frees lthy [mapx] (map (pair "f") Ts); |
|
1015 val t = Term.list_comb (mapx, map (Var o apfst (rpair 0)) fs); |
|
1016 in |
|
1017 Drule.instantiate' (map (SOME o certifyT lthy) [U, T]) [SOME (certify lthy t)] |
|
1018 @{thm if_distrib} |
1005 end; |
1019 end; |
1006 |
1020 |
1007 val crgsss' = map (map (map (intr_corec_likes gunfolds (K I) (K I)))) crgsss; |
1021 val nested_map_if_distribs = map mk_map_if_distrib nested_bnfs; |
1008 val cshsss' = |
|
1009 map (map (map (intr_corec_likes hcorecs (curry mk_sumT) (tack z)))) cshsss; |
|
1010 |
|
1011 val unfold_goalss = |
|
1012 map8 (map4 oooo mk_goal pgss) cs cpss gunfolds ns kss ctrss mss crgsss'; |
|
1013 val corec_goalss = |
|
1014 map8 (map4 oooo mk_goal phss) cs cpss hcorecs ns kss ctrss mss cshsss'; |
|
1015 |
1022 |
1016 val unfold_tacss = |
1023 val unfold_tacss = |
1017 map3 (map oo mk_corec_like_tac unfold_defs nesting_map_ids'') fp_fold_thms |
1024 map3 (map oo mk_corec_like_tac unfold_defs [] [] nesting_map_ids'' []) |
1018 pre_map_defs ctr_defss; |
1025 fp_fold_thms pre_map_defs ctr_defss; |
1019 val corec_tacss = |
1026 val corec_tacss = |
1020 map3 (map oo mk_corec_like_tac corec_defs nesting_map_ids'') fp_rec_thms pre_map_defs |
1027 map3 (map oo mk_corec_like_tac corec_defs nested_map_comps'' nested_map_comp's |
1021 ctr_defss; |
1028 (nested_map_ids'' @ nesting_map_ids'') nested_map_if_distribs) |
|
1029 fp_rec_thms pre_map_defs ctr_defss; |
1022 |
1030 |
1023 fun prove goal tac = |
1031 fun prove goal tac = |
1024 Skip_Proof.prove lthy [] [] goal (tac o #context) |> Thm.close_derivation; |
1032 Skip_Proof.prove lthy [] [] goal (tac o #context) |> Thm.close_derivation; |
1025 |
1033 |
1026 val unfold_thmss = map2 (map2 prove) unfold_goalss unfold_tacss; |
1034 val unfold_thmss = map2 (map2 prove) unfold_goalss unfold_tacss; |
1027 val corec_thmss = |
1035 val corec_thmss = map2 (map2 prove) corec_goalss corec_tacss; |
1028 map2 (map2 prove) corec_goalss corec_tacss |
|
1029 |> map (map (unfold_thms lthy @{thms sum_case_if})); |
|
1030 |
|
1031 val unfold_safesss = map2 (map2 (map2 (curry (op =)))) crgsss' crgsss; |
|
1032 val corec_safesss = map2 (map2 (map2 (curry (op =)))) cshsss' cshsss; |
|
1033 |
1036 |
1034 val filter_safesss = |
1037 val filter_safesss = |
1035 map2 (map_filter (fn (safes, thm) => if forall I safes then SOME thm else NONE) oo |
1038 map2 (map_filter (fn (safes, thm) => if forall I safes then SOME thm else NONE) oo |
1036 curry (op ~~)); |
1039 curry (op ~~)) (map2 (map2 (map2 (member (op =)))) cgssss crgsss); |
1037 |
1040 |
1038 val safe_unfold_thmss = filter_safesss unfold_safesss unfold_thmss; |
1041 val safe_unfold_thmss = filter_safesss unfold_thmss; |
1039 val safe_corec_thmss = filter_safesss corec_safesss corec_thmss; |
1042 val safe_corec_thmss = filter_safesss corec_thmss; |
1040 in |
1043 in |
1041 (unfold_thmss, corec_thmss, safe_unfold_thmss, safe_corec_thmss) |
1044 (unfold_thmss, corec_thmss, safe_unfold_thmss, safe_corec_thmss) |
1042 end; |
1045 end; |
1043 |
1046 |
1044 val (disc_unfold_iff_thmss, disc_corec_iff_thmss) = |
1047 val (disc_unfold_iff_thmss, disc_corec_iff_thmss) = |