19 thm list -> thm list -> BNF_Def.BNF list -> BNF_Def.BNF list -> typ list -> typ list -> |
19 thm list -> thm list -> BNF_Def.BNF list -> BNF_Def.BNF list -> typ list -> typ list -> |
20 typ list -> term list list -> thm list list -> term list -> term list -> thm list -> thm list -> |
20 typ list -> term list list -> thm list list -> term list -> term list -> thm list -> thm list -> |
21 Proof.context -> |
21 Proof.context -> |
22 (thm * thm list * Args.src list) * (thm list list * Args.src list) |
22 (thm * thm list * Args.src list) * (thm list list * Args.src list) |
23 * (thm list list * Args.src list) |
23 * (thm list list * Args.src list) |
24 val derive_coinduct_unfold_corec_thms_for_types: Proof.context -> Proof.context -> |
24 val derive_coinduct_unfold_corec_thms_for_types: BNF_Def.BNF list -> term list -> term list -> |
25 BNF_Def.BNF list -> thm -> thm -> thm list -> thm list -> thm list -> BNF_Def.BNF list -> |
25 thm -> thm -> thm list -> thm list -> thm list -> BNF_Def.BNF list -> BNF_Def.BNF list -> |
26 BNF_Def.BNF list -> typ list -> typ list -> typ list -> int list list -> int list list -> |
26 typ list -> typ list -> typ list -> int list list -> int list list -> int list -> |
27 int list -> term list -> term list list -> term list list -> term list list list list -> |
27 term list list -> thm list list -> BNF_Ctr_Sugar.ctr_wrap_result list -> term list -> |
28 term list list list list -> term list list -> term list list list list -> |
28 term list -> thm list -> thm list -> Proof.context -> |
29 term list list list list -> term list list -> thm list list -> |
|
30 BNF_Ctr_Sugar.ctr_wrap_result list -> term list -> term list -> thm list -> thm list -> |
|
31 Proof.context -> |
|
32 (thm * thm list * thm * thm list * Args.src list) * (thm list list * thm list list * 'e list) |
29 (thm * thm list * thm * thm list * Args.src list) * (thm list list * thm list list * 'e list) |
33 * (thm list list * thm list list) * (thm list list * thm list list * Args.src list) |
30 * (thm list list * thm list list) * (thm list list * thm list list * Args.src list) |
34 * (thm list list * thm list list * Args.src list) |
31 * (thm list list * thm list list * Args.src list) |
35 * (thm list list * thm list list * Args.src list) |
32 * (thm list list * thm list list * Args.src list) |
36 |
33 |
194 map (mk_rec_like lfp As Cs) fp_rec_likes0 |
197 map (mk_rec_like lfp As Cs) fp_rec_likes0 |
195 |> (fn ts => (ts, mk_fp_rec_like_fun_types ts)); |
198 |> (fn ts => (ts, mk_fp_rec_like_fun_types ts)); |
196 |
199 |
197 fun mk_rec_like_fun_arg_typess n ms = map2 dest_tupleT ms o dest_sumTN_balanced n o domain_type; |
200 fun mk_rec_like_fun_arg_typess n ms = map2 dest_tupleT ms o dest_sumTN_balanced n o domain_type; |
198 |
201 |
199 fun project_recT fpTs proj = |
202 fun massage_rec_fun_arg_typesss fpTs = |
200 let |
203 let |
201 fun project (Type (s as @{type_name prod}, Ts as [T, U])) = |
204 fun project_recT proj = |
202 if member (op =) fpTs T then proj (T, U) else Type (s, map project Ts) |
205 let |
203 | project (Type (s, Ts)) = Type (s, map project Ts) |
206 fun project (Type (s as @{type_name prod}, Ts as [T, U])) = |
204 | project T = T; |
207 if member (op =) fpTs T then proj (T, U) else Type (s, map project Ts) |
205 in project end; |
208 | project (Type (s, Ts)) = Type (s, map project Ts) |
206 |
209 | project T = T; |
207 fun unzip_recT fpTs T = |
210 in project end; |
208 if exists_subtype_in fpTs T then ([project_recT fpTs fst T], [project_recT fpTs snd T]) |
211 fun unzip_recT T = |
209 else ([T], []); |
212 if exists_subtype_in fpTs T then ([project_recT fst T], [project_recT snd T]) else ([T], []); |
210 |
213 in |
211 fun massage_rec_fun_arg_typesss fpTs = map (map (flat_rec (unzip_recT fpTs))); |
214 map (map (flat_rec unzip_recT)) |
|
215 end; |
212 |
216 |
213 val mk_fold_fun_typess = map2 (map2 (curry (op --->))); |
217 val mk_fold_fun_typess = map2 (map2 (curry (op --->))); |
214 val mk_rec_fun_typess = mk_fold_fun_typess oo massage_rec_fun_arg_typesss; |
218 val mk_rec_fun_typess = mk_fold_fun_typess oo massage_rec_fun_arg_typesss; |
|
219 |
|
220 fun mk_corec_like_pred_types n = replicate (Int.max (0, n - 1)) o mk_pred1T; |
|
221 |
|
222 fun mk_unfold_corec_types fpTs Cs ns mss dtor_unfold_fun_Ts dtor_corec_fun_Ts = |
|
223 let |
|
224 (*avoid "'a itself" arguments in coiterators and corecursors*) |
|
225 fun repair_arity [0] = [1] |
|
226 | repair_arity ms = ms; |
|
227 |
|
228 fun project_corecT proj = |
|
229 let |
|
230 fun project (Type (s as @{type_name sum}, Ts as [T, U])) = |
|
231 if member (op =) fpTs T then proj (T, U) else Type (s, map project Ts) |
|
232 | project (Type (s, Ts)) = Type (s, map project Ts) |
|
233 | project T = T; |
|
234 in project end; |
|
235 |
|
236 fun unzip_corecT T = |
|
237 if exists_subtype_in fpTs T then [project_corecT fst T, project_corecT snd T] else [T]; |
|
238 |
|
239 val p_Tss = map2 mk_corec_like_pred_types ns Cs; |
|
240 |
|
241 fun mk_types maybe_unzipT fun_Ts = |
|
242 let |
|
243 val f_sum_prod_Ts = map range_type fun_Ts; |
|
244 val f_prod_Tss = map2 dest_sumTN_balanced ns f_sum_prod_Ts; |
|
245 val f_Tsss = map2 (map2 dest_tupleT o repair_arity) mss f_prod_Tss; |
|
246 val f_Tssss = |
|
247 map2 (fn C => map (map (map (curry (op -->) C) o maybe_unzipT))) Cs f_Tsss; |
|
248 val q_Tssss = |
|
249 map (map (map (fn [_] => [] | [_, C] => [mk_pred1T (domain_type C)]))) f_Tssss; |
|
250 val pf_Tss = map3 flat_preds_predsss_gettersss p_Tss q_Tssss f_Tssss; |
|
251 in (q_Tssss, f_sum_prod_Ts, f_Tsss, f_Tssss, pf_Tss) end; |
|
252 in |
|
253 (p_Tss, mk_types single dtor_unfold_fun_Ts, mk_types unzip_corecT dtor_corec_fun_Ts) |
|
254 end |
|
255 |
|
256 fun mk_unfold_corec_vars Cs p_Tss g_Tssss r_Tssss h_Tssss s_Tssss lthy = |
|
257 let |
|
258 val (((cs, pss), gssss), lthy) = |
|
259 lthy |
|
260 |> mk_Frees "a" Cs |
|
261 ||>> mk_Freess "p" p_Tss |
|
262 ||>> mk_Freessss "g" g_Tssss; |
|
263 val rssss = map (map (map (fn [] => []))) r_Tssss; |
|
264 |
|
265 val hssss_hd = map2 (map2 (map2 (fn T :: _ => fn [g] => retype_free T g))) h_Tssss gssss; |
|
266 val ((sssss, hssss_tl), lthy) = |
|
267 lthy |
|
268 |> mk_Freessss "q" s_Tssss |
|
269 ||>> mk_Freessss "h" (map (map (map tl)) h_Tssss); |
|
270 val hssss = map2 (map2 (map2 cons)) hssss_hd hssss_tl; |
|
271 in |
|
272 ((cs, pss, (gssss, rssss), (hssss, sssss)), lthy) |
|
273 end; |
|
274 |
|
275 fun mk_corec_like_terms cs pss qssss fssss = |
|
276 let |
|
277 val pfss = map3 flat_preds_predsss_gettersss pss qssss fssss; |
|
278 val cqssss = map2 (map o map o map o rapp) cs qssss; |
|
279 val cfssss = map2 (map o map o map o rapp) cs fssss; |
|
280 in (pfss, cqssss, cfssss) end; |
215 |
281 |
216 fun mk_map live Ts Us t = |
282 fun mk_map live Ts Us t = |
217 let val (Type (_, Ts0), Type (_, Us0)) = strip_typeN (live + 1) (fastype_of t) |>> List.last in |
283 let val (Type (_, Ts0), Type (_, Us0)) = strip_typeN (live + 1) (fastype_of t) |>> List.last in |
218 Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) t |
284 Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) t |
219 end; |
285 end; |
468 lthy |
536 lthy |
469 |> mk_Frees "R" (map (fn T => mk_pred2T T T) fpTs) |
537 |> mk_Frees "R" (map (fn T => mk_pred2T T T) fpTs) |
470 ||>> Variable.variant_fixes fp_b_names |
538 ||>> Variable.variant_fixes fp_b_names |
471 ||>> Variable.variant_fixes (map (suffix "'") fp_b_names); |
539 ||>> Variable.variant_fixes (map (suffix "'") fp_b_names); |
472 |
540 |
|
541 val (p_Tss, (r_Tssss, g_sum_prod_Ts, g_Tsss, g_Tssss, pg_Tss), |
|
542 (s_Tssss, h_sum_prod_Ts, h_Tsss, h_Tssss, ph_Tss)) = |
|
543 mk_unfold_corec_types fpTs Cs ns mss dtor_unfold_fun_Ts dtor_corec_fun_Ts; |
|
544 |
|
545 val ((cs, pss, (gssss, rssss), (hssss, sssss)), names_lthy) = |
|
546 mk_unfold_corec_vars Cs p_Tss g_Tssss r_Tssss h_Tssss s_Tssss names_lthy; |
|
547 |
|
548 val cpss = map2 (map o rapp) cs pss; |
|
549 |
473 val us = map2 (curry Free) us' fpTs; |
550 val us = map2 (curry Free) us' fpTs; |
474 val udiscss = map2 (map o rapp) us discss; |
551 val udiscss = map2 (map o rapp) us discss; |
475 val uselsss = map2 (map o map o rapp) us selsss; |
552 val uselsss = map2 (map o map o rapp) us selsss; |
476 |
553 |
477 val vs = map2 (curry Free) vs' fpTs; |
554 val vs = map2 (curry Free) vs' fpTs; |
478 val vdiscss = map2 (map o rapp) vs discss; |
555 val vdiscss = map2 (map o rapp) vs discss; |
479 val vselsss = map2 (map o map o rapp) vs selsss; |
556 val vselsss = map2 (map o map o rapp) vs selsss; |
|
557 |
|
558 val (pgss, crssss, cgssss) = mk_corec_like_terms cs pss rssss gssss; |
|
559 val (phss, csssss, chssss) = mk_corec_like_terms cs pss sssss hssss; |
480 |
560 |
481 val ((coinduct_thms, coinduct_thm), (strong_coinduct_thms, strong_coinduct_thm)) = |
561 val ((coinduct_thms, coinduct_thm), (strong_coinduct_thms, strong_coinduct_thm)) = |
482 let |
562 let |
483 val uvrs = map3 (fn r => fn u => fn v => r $ u $ v) rs us vs; |
563 val uvrs = map3 (fn r => fn u => fn v => r $ u $ v) rs us vs; |
484 val uv_eqs = map2 (curry HOLogic.mk_eq) us vs; |
564 val uv_eqs = map2 (curry HOLogic.mk_eq) us vs; |
892 ((((gss, g_Tss, ysss), (hss, h_Tss, zsss)), |
972 ((((gss, g_Tss, ysss), (hss, h_Tss, zsss)), |
893 ([], [], (([], [], []), ([], [], [])), (([], [], []), ([], [], [])))), lthy) |
973 ([], [], (([], [], []), ([], [], [])), (([], [], []), ([], [], [])))), lthy) |
894 end |
974 end |
895 else |
975 else |
896 let |
976 let |
897 (*avoid "'a itself" arguments in coiterators and corecursors*) |
977 val (p_Tss, (r_Tssss, g_sum_prod_Ts, g_Tsss, g_Tssss, pg_Tss), |
898 val mss' = map (fn [0] => [1] | ms => ms) mss; |
978 (s_Tssss, h_sum_prod_Ts, h_Tsss, h_Tssss, ph_Tss)) = |
899 |
979 mk_unfold_corec_types fpTs Cs ns mss fp_fold_fun_Ts fp_rec_fun_Ts; |
900 val p_Tss = map2 (fn n => replicate (Int.max (0, n - 1)) o mk_pred1T) ns Cs; |
980 |
901 |
981 val ((cs, pss, (gssss, rssss), (hssss, sssss)), lthy) = |
902 fun flat_predss_getterss qss fss = maps (op @) (qss ~~ fss); |
982 mk_unfold_corec_vars Cs p_Tss g_Tssss r_Tssss h_Tssss s_Tssss lthy; |
903 |
|
904 fun flat_preds_predsss_gettersss [] [qss] [fss] = flat_predss_getterss qss fss |
|
905 | flat_preds_predsss_gettersss (p :: ps) (qss :: qsss) (fss :: fsss) = |
|
906 p :: flat_predss_getterss qss fss @ flat_preds_predsss_gettersss ps qsss fsss; |
|
907 |
|
908 fun mk_types maybe_unzipT fun_Ts = |
|
909 let |
|
910 val f_sum_prod_Ts = map range_type fun_Ts; |
|
911 val f_prod_Tss = map2 dest_sumTN_balanced ns f_sum_prod_Ts; |
|
912 val f_Tsss = map2 (map2 dest_tupleT) mss' f_prod_Tss; |
|
913 val f_Tssss = |
|
914 map2 (fn C => map (map (map (curry (op -->) C) o maybe_unzipT))) Cs f_Tsss; |
|
915 val q_Tssss = |
|
916 map (map (map (fn [_] => [] | [_, C] => [mk_pred1T (domain_type C)]))) f_Tssss; |
|
917 val pf_Tss = map3 flat_preds_predsss_gettersss p_Tss q_Tssss f_Tssss; |
|
918 in (q_Tssss, f_sum_prod_Ts, f_Tsss, f_Tssss, pf_Tss) end; |
|
919 |
|
920 val (r_Tssss, g_sum_prod_Ts, g_Tsss, g_Tssss, pg_Tss) = mk_types single fp_fold_fun_Ts; |
|
921 |
|
922 val (((cs, pss), gssss), lthy) = |
|
923 lthy |
|
924 |> mk_Frees "a" Cs |
|
925 ||>> mk_Freess "p" p_Tss |
|
926 ||>> mk_Freessss "g" g_Tssss; |
|
927 val rssss = map (map (map (fn [] => []))) r_Tssss; |
|
928 |
|
929 fun proj_corecT proj (Type (s as @{type_name sum}, Ts as [T, U])) = |
|
930 if member (op =) fpTs T then proj (T, U) else Type (s, map (proj_corecT proj) Ts) |
|
931 | proj_corecT proj (Type (s, Ts)) = Type (s, map (proj_corecT proj) Ts) |
|
932 | proj_corecT _ T = T; |
|
933 |
|
934 fun unzip_corecT T = |
|
935 if exists_subtype_in fpTs T then [proj_corecT fst T, proj_corecT snd T] else [T]; |
|
936 |
|
937 val (s_Tssss, h_sum_prod_Ts, h_Tsss, h_Tssss, ph_Tss) = |
|
938 mk_types unzip_corecT fp_rec_fun_Ts; |
|
939 |
|
940 val hssss_hd = map2 (map2 (map2 (fn T :: _ => fn [g] => retype_free T g))) h_Tssss gssss; |
|
941 val ((sssss, hssss_tl), lthy) = |
|
942 lthy |
|
943 |> mk_Freessss "q" s_Tssss |
|
944 ||>> mk_Freessss "h" (map (map (map tl)) h_Tssss); |
|
945 val hssss = map2 (map2 (map2 cons)) hssss_hd hssss_tl; |
|
946 |
983 |
947 val cpss = map2 (map o rapp) cs pss; |
984 val cpss = map2 (map o rapp) cs pss; |
948 |
|
949 fun mk_terms qssss fssss = |
|
950 let |
|
951 val pfss = map3 flat_preds_predsss_gettersss pss qssss fssss; |
|
952 val cqssss = map2 (map o map o map o rapp) cs qssss; |
|
953 val cfssss = map2 (map o map o map o rapp) cs fssss; |
|
954 in (pfss, cqssss, cfssss) end; |
|
955 in |
985 in |
956 (((([], [], []), ([], [], [])), |
986 (((([], [], []), ([], [], [])), |
957 (cs, cpss, (mk_terms rssss gssss, (g_sum_prod_Ts, g_Tsss, pg_Tss)), |
987 (cs, cpss, (mk_corec_like_terms cs pss rssss gssss, (g_sum_prod_Ts, g_Tsss, pg_Tss)), |
958 (mk_terms sssss hssss, (h_sum_prod_Ts, h_Tsss, ph_Tss)))), lthy) |
988 (mk_corec_like_terms cs pss sssss hssss, (h_sum_prod_Ts, h_Tsss, ph_Tss)))), lthy) |
959 end; |
989 end; |
960 |
990 |
961 fun define_ctrs_case_for_type (((((((((((((((((((((((((fp_bnf, fp_b), fpT), C), ctor), dtor), |
991 fun define_ctrs_case_for_type (((((((((((((((((((((((((fp_bnf, fp_b), fpT), C), ctor), dtor), |
962 fp_fold), fp_rec), ctor_dtor), dtor_ctor), ctor_inject), pre_map_def), pre_set_defs), |
992 fp_fold), fp_rec), ctor_dtor), dtor_ctor), ctor_inject), pre_map_def), pre_set_defs), |
963 pre_rel_def), fp_map_thm), fp_set_thms), fp_rel_thm), n), ks), ms), ctr_bindings), |
993 pre_rel_def), fp_map_thm), fp_set_thms), fp_rel_thm), n), ks), ms), ctr_bindings), |
1309 (unfold_thmss, corec_thmss, corec_like_attrs), |
1339 (unfold_thmss, corec_thmss, corec_like_attrs), |
1310 (safe_unfold_thmss, safe_corec_thmss), |
1340 (safe_unfold_thmss, safe_corec_thmss), |
1311 (disc_unfold_thmss, disc_corec_thmss, disc_corec_like_attrs), |
1341 (disc_unfold_thmss, disc_corec_thmss, disc_corec_like_attrs), |
1312 (disc_unfold_iff_thmss, disc_corec_iff_thmss, disc_corec_like_iff_attrs), |
1342 (disc_unfold_iff_thmss, disc_corec_iff_thmss, disc_corec_like_iff_attrs), |
1313 (sel_unfold_thmss, sel_corec_thmss, sel_corec_like_attrs)) = |
1343 (sel_unfold_thmss, sel_corec_thmss, sel_corec_like_attrs)) = |
1314 derive_coinduct_unfold_corec_thms_for_types names_lthy0 no_defs_lthy pre_bnfs fp_induct |
1344 derive_coinduct_unfold_corec_thms_for_types pre_bnfs fp_folds0 fp_recs0 fp_induct |
1315 fp_strong_induct dtor_ctors fp_fold_thms fp_rec_thms nesting_bnfs nested_bnfs fpTs Cs As |
1345 fp_strong_induct dtor_ctors fp_fold_thms fp_rec_thms nesting_bnfs nested_bnfs fpTs Cs As |
1316 kss mss ns cs cpss pgss crssss cgssss phss csssss chssss ctrss ctr_defss ctr_wrap_ress |
1346 kss mss ns ctrss ctr_defss ctr_wrap_ress unfolds corecs unfold_defs corec_defs lthy; |
1317 unfolds corecs unfold_defs corec_defs lthy; |
|
1318 |
1347 |
1319 fun coinduct_type_attr T_name = Attrib.internal (K (Induct.coinduct_type T_name)); |
1348 fun coinduct_type_attr T_name = Attrib.internal (K (Induct.coinduct_type T_name)); |
1320 |
1349 |
1321 fun flat_corec_like_thms corec_likes disc_corec_likes sel_corec_likes = |
1350 fun flat_corec_like_thms corec_likes disc_corec_likes sel_corec_likes = |
1322 corec_likes @ disc_corec_likes @ sel_corec_likes; |
1351 corec_likes @ disc_corec_likes @ sel_corec_likes; |