234 |
234 |
235 val (((fold_strs, fold_strs'), (rec_strs, rec_strs')), names_lthy) = names_lthy |
235 val (((fold_strs, fold_strs'), (rec_strs, rec_strs')), names_lthy) = names_lthy |
236 |> mk_Frees' "s" fold_strTs |
236 |> mk_Frees' "s" fold_strTs |
237 ||>> mk_Frees' "s" rec_strTs; |
237 ||>> mk_Frees' "s" rec_strTs; |
238 |
238 |
239 val co_iters = of_fp_res #xtor_co_iterss; |
239 val co_folds = of_fp_res #xtor_co_folds; |
|
240 val co_recs = of_fp_res #xtor_co_recs; |
240 val ns = map (length o #Ts o #fp_res) fp_sugars; |
241 val ns = map (length o #Ts o #fp_res) fp_sugars; |
241 |
242 |
242 fun substT rho (Type (@{type_name "fun"}, [T, U])) = substT rho T --> substT rho U |
243 fun substT rho (Type (@{type_name "fun"}, [T, U])) = substT rho T --> substT rho U |
243 | substT rho (Type (s, Ts)) = Type (s, map (typ_subst_nonatomic rho) Ts) |
244 | substT rho (Type (s, Ts)) = Type (s, map (typ_subst_nonatomic rho) Ts) |
244 | substT _ T = T; |
245 | substT _ T = T; |
245 |
246 |
246 val typ_subst_nonatomic_sorted = fold_rev (typ_subst_nonatomic o single); |
247 val typ_subst_nonatomic_sorted = fold_rev (typ_subst_nonatomic o single); |
247 |
248 |
248 fun force_iter is_rec i TU TU_rec raw_iters = |
249 fun force_iter is_rec i TU TU_rec raw_fold raw_rec = |
249 let |
250 let |
250 val thy = Proof_Context.theory_of lthy; |
251 val thy = Proof_Context.theory_of lthy; |
251 |
252 |
252 val approx_fold = un_fold_of raw_iters |
253 val approx_fold = raw_fold |
253 |> force_typ names_lthy |
254 |> force_typ names_lthy |
254 (replicate (nth ns i) dummyT ---> (if is_rec then TU_rec else TU)); |
255 (replicate (nth ns i) dummyT ---> (if is_rec then TU_rec else TU)); |
255 val subst = Term.typ_subst_atomic fold_thetaAs; |
256 val subst = Term.typ_subst_atomic fold_thetaAs; |
256 |
257 |
257 fun mk_fp_absT_repT fp_repT fp_absT = mk_absT thy fp_repT fp_absT ooo mk_repT; |
258 fun mk_fp_absT_repT fp_repT fp_absT = mk_absT thy fp_repT fp_absT ooo mk_repT; |
267 |> uncurry (map2 mk_co_algT); |
268 |> uncurry (map2 mk_co_algT); |
268 val cands = map2 mk_co_algT fold_preTs' Xs; |
269 val cands = map2 mk_co_algT fold_preTs' Xs; |
269 |
270 |
270 val js = find_indices Type.could_unify TUs cands; |
271 val js = find_indices Type.could_unify TUs cands; |
271 val Tpats = map (fn j => mk_co_algT (nth fold_pre_deads_only_Ts j) (nth Xs j)) js; |
272 val Tpats = map (fn j => mk_co_algT (nth fold_pre_deads_only_Ts j) (nth Xs j)) js; |
272 val iter = raw_iters |> (if is_rec then co_rec_of else un_fold_of); |
273 in |
273 in |
274 force_typ names_lthy (Tpats ---> TU) (if is_rec then raw_rec else raw_fold) |
274 force_typ names_lthy (Tpats ---> TU) iter |
|
275 end; |
275 end; |
276 |
276 |
277 fun mk_co_comp_abs_rep fp_absT absT fp_abs fp_rep abs rep t = |
277 fun mk_co_comp_abs_rep fp_absT absT fp_abs fp_rep abs rep t = |
278 fp_case fp (HOLogic.mk_comp (HOLogic.mk_comp (t, mk_abs absT abs), mk_rep fp_absT fp_rep)) |
278 fp_case fp (HOLogic.mk_comp (HOLogic.mk_comp (t, mk_abs absT abs), mk_rep fp_absT fp_rep)) |
279 (HOLogic.mk_comp (mk_abs fp_absT fp_abs, HOLogic.mk_comp (mk_rep absT rep, t))); |
279 (HOLogic.mk_comp (mk_abs fp_absT fp_abs, HOLogic.mk_comp (mk_rep absT rep, t))); |
284 |
284 |
285 val x = co_alg_argT TU; |
285 val x = co_alg_argT TU; |
286 val i = find_index (fn T => x = T) Xs; |
286 val i = find_index (fn T => x = T) Xs; |
287 val TUiter = |
287 val TUiter = |
288 (case find_first (fn f => body_fun_type (fastype_of f) = TU) iters of |
288 (case find_first (fn f => body_fun_type (fastype_of f) = TU) iters of |
289 NONE => nth co_iters i |
289 NONE => |
290 |> force_iter is_rec i |
290 force_iter is_rec i |
291 (TU |> (is_none b_opt andalso not is_rec) ? substT (fpTs ~~ Xs)) |
291 (TU |> (is_none b_opt andalso not is_rec) ? substT (fpTs ~~ Xs)) |
292 (TU |> (is_none b_opt) ? substT (map2 mk_co_productT fpTs Xs ~~ Xs)) |
292 (TU |> is_none b_opt ? substT (map2 mk_co_productT fpTs Xs ~~ Xs)) |
|
293 (nth co_folds i) (nth co_recs i) |
293 | SOME f => f); |
294 | SOME f => f); |
294 |
295 |
295 val TUs = binder_fun_types (fastype_of TUiter); |
296 val TUs = binder_fun_types (fastype_of TUiter); |
296 val iter_preTs = if is_rec then rec_preTs else fold_preTs; |
297 val iter_preTs = if is_rec then rec_preTs else fold_preTs; |
297 val iter_strs = if is_rec then rec_strs else fold_strs; |
298 val iter_strs = if is_rec then rec_strs else fold_strs; |
371 val phi = Proof_Context.export_morphism raw_lthy lthy; |
372 val phi = Proof_Context.export_morphism raw_lthy lthy; |
372 |
373 |
373 val un_folds = map (Morphism.term phi) raw_un_folds; |
374 val un_folds = map (Morphism.term phi) raw_un_folds; |
374 val co_recs = map (Morphism.term phi) raw_co_recs; |
375 val co_recs = map (Morphism.term phi) raw_co_recs; |
375 |
376 |
|
377 val fp_fold_o_maps = of_fp_res #xtor_co_fold_o_map_thms; |
|
378 val fp_rec_o_maps = of_fp_res #xtor_co_rec_o_map_thms; |
|
379 |
376 val (xtor_un_fold_thms, xtor_co_rec_thms) = |
380 val (xtor_un_fold_thms, xtor_co_rec_thms) = |
377 let |
381 let |
378 val folds = map (fn f => Term.list_comb (f, fold_strs)) raw_un_folds; |
382 val folds = map (fn f => Term.list_comb (f, fold_strs)) raw_un_folds; |
379 val recs = map (fn r => Term.list_comb (r, rec_strs)) raw_co_recs; |
383 val recs = map (fn r => Term.list_comb (r, rec_strs)) raw_co_recs; |
380 val fold_mapTs = co_swap (As @ fpTs, As @ Xs); |
384 val fold_mapTs = co_swap (As @ fpTs, As @ Xs); |
417 val pre_map_defs = no_refl (map map_def_of_bnf bnfs); |
421 val pre_map_defs = no_refl (map map_def_of_bnf bnfs); |
418 val fp_pre_map_defs = no_refl (map map_def_of_bnf pre_bnfs); |
422 val fp_pre_map_defs = no_refl (map map_def_of_bnf pre_bnfs); |
419 |
423 |
420 val unfold_map = map (unfold_thms lthy (id_apply :: pre_map_defs)); |
424 val unfold_map = map (unfold_thms lthy (id_apply :: pre_map_defs)); |
421 |
425 |
422 val fp_xtor_co_iterss = of_fp_res #xtor_co_iter_thmss; |
426 val fp_xtor_un_folds = map (mk_pointfree lthy) (of_fp_res #xtor_co_fold_thms); |
423 val fp_xtor_un_folds = map (mk_pointfree lthy o un_fold_of) fp_xtor_co_iterss; |
427 val fp_xtor_co_recs = map (mk_pointfree lthy) (of_fp_res #xtor_co_rec_thms); |
424 val fp_xtor_co_recs = map (mk_pointfree lthy o co_rec_of) fp_xtor_co_iterss; |
428 |
425 |
|
426 val fp_co_iter_o_mapss = of_fp_res #xtor_co_iter_o_map_thmss; |
|
427 val fp_fold_o_maps = map un_fold_of fp_co_iter_o_mapss; |
|
428 val fp_rec_o_maps = map co_rec_of fp_co_iter_o_mapss; |
|
429 val fold_thms = fp_case fp @{thm comp_assoc} @{thm comp_assoc[symmetric]} :: |
429 val fold_thms = fp_case fp @{thm comp_assoc} @{thm comp_assoc[symmetric]} :: |
430 map (fn thm => thm RS rewrite_comp_comp) @{thms map_pair.comp sum_map.comp} @ |
430 map (fn thm => thm RS rewrite_comp_comp) @{thms map_pair.comp sum_map.comp} @ |
431 @{thms id_apply comp_id id_comp map_pair.comp map_pair.id sum_map.comp sum_map.id}; |
431 @{thms id_apply comp_id id_comp map_pair.comp map_pair.id sum_map.comp sum_map.id}; |
432 val rec_thms = fold_thms @ fp_case fp |
432 val rec_thms = fold_thms @ fp_case fp |
433 @{thms fst_convol map_pair_o_convol convol_o} |
433 @{thms fst_convol map_pair_o_convol convol_o} |
462 end; |
462 end; |
463 |
463 |
464 (* These results are half broken. This is deliberate. We care only about those fields that are |
464 (* These results are half broken. This is deliberate. We care only about those fields that are |
465 used by "primrec", "primcorecursive", and "datatype_compat". *) |
465 used by "primrec", "primcorecursive", and "datatype_compat". *) |
466 val fp_res = |
466 val fp_res = |
467 ({Ts = fpTs, |
467 ({Ts = fpTs, bnfs = of_fp_res #bnfs, dtors = dtors, ctors = ctors, xtor_co_folds = un_folds, |
468 bnfs = of_fp_res #bnfs, |
468 xtor_co_recs = co_recs, xtor_co_induct = xtor_co_induct_thm, |
469 dtors = dtors, |
|
470 ctors = ctors, |
|
471 xtor_co_iterss = transpose [un_folds, co_recs], |
|
472 xtor_co_induct = xtor_co_induct_thm, |
|
473 dtor_ctors = of_fp_res #dtor_ctors (*too general types*), |
469 dtor_ctors = of_fp_res #dtor_ctors (*too general types*), |
474 ctor_dtors = of_fp_res #ctor_dtors (*too general types*), |
470 ctor_dtors = of_fp_res #ctor_dtors (*too general types*), |
475 ctor_injects = of_fp_res #ctor_injects (*too general types*), |
471 ctor_injects = of_fp_res #ctor_injects (*too general types*), |
476 dtor_injects = of_fp_res #dtor_injects (*too general types*), |
472 dtor_injects = of_fp_res #dtor_injects (*too general types*), |
477 xtor_map_thms = of_fp_res #xtor_map_thms (*too general types and terms*), |
473 xtor_map_thms = of_fp_res #xtor_map_thms (*too general types and terms*), |
478 xtor_set_thmss = of_fp_res #xtor_set_thmss (*too general types and terms*), |
474 xtor_set_thmss = of_fp_res #xtor_set_thmss (*too general types and terms*), |
479 xtor_rel_thms = of_fp_res #xtor_rel_thms (*too general types and terms*), |
475 xtor_rel_thms = of_fp_res #xtor_rel_thms (*too general types and terms*), |
480 xtor_co_iter_thmss = transpose [xtor_un_fold_thms, xtor_co_rec_thms], |
476 xtor_co_fold_thms = xtor_un_fold_thms, |
481 xtor_co_iter_o_map_thmss = of_fp_res #xtor_co_iter_o_map_thmss |
477 xtor_co_rec_thms = xtor_co_rec_thms, |
482 (*theorem about old constant*), |
478 xtor_co_fold_o_map_thms = fp_fold_o_maps (*theorems about old constants*), |
|
479 xtor_co_rec_o_map_thms = fp_rec_o_maps (*theorems about old constants*), |
483 rel_xtor_co_induct_thm = rel_xtor_co_induct_thm} |
480 rel_xtor_co_induct_thm = rel_xtor_co_induct_thm} |
484 |> morph_fp_result (Morphism.term_morphism "BNF" (singleton (Variable.polymorphic lthy)))); |
481 |> morph_fp_result (Morphism.term_morphism "BNF" (singleton (Variable.polymorphic lthy)))); |
485 in |
482 in |
486 (fp_res, lthy) |
483 (fp_res, lthy) |
487 end; |
484 end; |