45 Const (@{const_name sum_map}, fT --> gT --> mk_sumT (fAT, gAT) --> mk_sumT (fBT, gBT)) $ f $ g |
45 Const (@{const_name sum_map}, fT --> gT --> mk_sumT (fAT, gAT) --> mk_sumT (fBT, gBT)) $ f $ g |
46 end; |
46 end; |
47 |
47 |
48 fun construct_mutualized_fp fp fpTs fp_sugars bs resBs (resDs, Dss) bnfs lthy = |
48 fun construct_mutualized_fp fp fpTs fp_sugars bs resBs (resDs, Dss) bnfs lthy = |
49 let |
49 let |
50 fun steal get = map (of_fp_sugar (get o #fp_res)) fp_sugars; |
50 fun steal_fp_res get = |
|
51 map (fn {fp_res, fp_res_index, ...} => nth (get fp_res) fp_res_index) fp_sugars; |
51 |
52 |
52 val n = length bnfs; |
53 val n = length bnfs; |
53 val deads = fold (union (op =)) Dss resDs; |
54 val deads = fold (union (op =)) Dss resDs; |
54 val As = subtract (op =) deads (map TFree resBs); |
55 val As = subtract (op =) deads (map TFree resBs); |
55 val names_lthy = fold Variable.declare_typ (As @ deads) lthy; |
56 val names_lthy = fold Variable.declare_typ (As @ deads) lthy; |
75 val mk_co_productT = curry (fp_case fp HOLogic.mk_prodT mk_sumT); |
76 val mk_co_productT = curry (fp_case fp HOLogic.mk_prodT mk_sumT); |
76 val dest_co_productT = fp_case fp HOLogic.dest_prodT dest_sumT; |
77 val dest_co_productT = fp_case fp HOLogic.dest_prodT dest_sumT; |
77 |
78 |
78 val ((ctors, dtors), (xtor's, xtors)) = |
79 val ((ctors, dtors), (xtor's, xtors)) = |
79 let |
80 let |
80 val ctors = map2 (force_typ names_lthy o (fn T => dummyT --> T)) fpTs (steal #ctors); |
81 val ctors = map2 (force_typ names_lthy o (fn T => dummyT --> T)) fpTs (steal_fp_res #ctors); |
81 val dtors = map2 (force_typ names_lthy o (fn T => T --> dummyT)) fpTs (steal #dtors); |
82 val dtors = map2 (force_typ names_lthy o (fn T => T --> dummyT)) fpTs (steal_fp_res #dtors); |
82 in |
83 in |
83 ((ctors, dtors), `(map (Term.subst_atomic_types theta)) (fp_case fp ctors dtors)) |
84 ((ctors, dtors), `(map (Term.subst_atomic_types theta)) (fp_case fp ctors dtors)) |
84 end; |
85 end; |
85 |
86 |
86 val xTs = map (domain_type o fastype_of) xtors; |
87 val xTs = map (domain_type o fastype_of) xtors; |
90 |> mk_Frees' "R" phiTs |
91 |> mk_Frees' "R" phiTs |
91 ||>> mk_Frees "S" pre_phiTs |
92 ||>> mk_Frees "S" pre_phiTs |
92 ||>> mk_Frees "x" xTs |
93 ||>> mk_Frees "x" xTs |
93 ||>> mk_Frees "y" yTs; |
94 ||>> mk_Frees "y" yTs; |
94 |
95 |
95 val fp_bnfs = steal #bnfs; |
96 val fp_bnfs = steal_fp_res #bnfs; |
96 val pre_bnfs = map (of_fp_sugar #pre_bnfs) fp_sugars; |
97 val pre_bnfs = map #pre_bnf fp_sugars; |
97 val pre_bnfss = map #pre_bnfs fp_sugars; |
|
98 val nesty_bnfss = map (fn sugar => #nested_bnfs sugar @ #nesting_bnfs sugar) fp_sugars; |
98 val nesty_bnfss = map (fn sugar => #nested_bnfs sugar @ #nesting_bnfs sugar) fp_sugars; |
99 val fp_nesty_bnfss = fp_bnfs :: nesty_bnfss; |
99 val fp_nesty_bnfss = fp_bnfs :: nesty_bnfss; |
100 val fp_nesty_bnfs = distinct (op = o pairself T_of_bnf) (flat fp_nesty_bnfss); |
100 val fp_nesty_bnfs = distinct (op = o pairself T_of_bnf) (flat fp_nesty_bnfss); |
101 |
101 |
102 val rels = |
102 val rels = |
124 map2 (fold_rev Term.absfree phis' oo mk_rel) fpTs fpTs' |
124 map2 (fold_rev Term.absfree phis' oo mk_rel) fpTs fpTs' |
125 end; |
125 end; |
126 |
126 |
127 val pre_rels = map2 (fn Ds => mk_rel_of_bnf Ds (As @ fpTs) (Bs @ fpTs')) Dss bnfs; |
127 val pre_rels = map2 (fn Ds => mk_rel_of_bnf Ds (As @ fpTs) (Bs @ fpTs')) Dss bnfs; |
128 |
128 |
129 val rel_unfoldss = map (maps (fn bnf => no_refl [rel_def_of_bnf bnf])) pre_bnfss; |
129 val rel_unfolds = maps (no_refl o single o rel_def_of_bnf) pre_bnfs; |
130 val rel_xtor_co_inducts = steal (split_conj_thm o #rel_xtor_co_induct_thm) |
130 val rel_xtor_co_inducts = steal_fp_res (split_conj_thm o #rel_xtor_co_induct_thm) |
131 |> map2 (fn unfs => unfold_thms lthy (id_apply :: unfs)) rel_unfoldss; |
131 |> map (unfold_thms lthy (id_apply :: rel_unfolds)); |
132 |
132 |
133 val rel_defs = map rel_def_of_bnf bnfs; |
133 val rel_defs = map rel_def_of_bnf bnfs; |
134 val rel_monos = map rel_mono_of_bnf bnfs; |
134 val rel_monos = map rel_mono_of_bnf bnfs; |
135 |
135 |
136 val rel_xtor_co_induct_thm = |
136 val rel_xtor_co_induct_thm = |
183 |
183 |
184 val (((fold_strs, fold_strs'), (rec_strs, rec_strs')), names_lthy) = names_lthy |
184 val (((fold_strs, fold_strs'), (rec_strs, rec_strs')), names_lthy) = names_lthy |
185 |> mk_Frees' "s" fold_strTs |
185 |> mk_Frees' "s" fold_strTs |
186 ||>> mk_Frees' "s" rec_strTs; |
186 ||>> mk_Frees' "s" rec_strTs; |
187 |
187 |
188 val co_iters = steal #xtor_co_iterss; |
188 val co_iters = steal_fp_res #xtor_co_iterss; |
189 val ns = map (length o #pre_bnfs) fp_sugars; |
189 val ns = map (length o #Ts o #fp_res) fp_sugars; |
|
190 |
190 fun substT rho (Type (@{type_name "fun"}, [T, U])) = substT rho T --> substT rho U |
191 fun substT rho (Type (@{type_name "fun"}, [T, U])) = substT rho T --> substT rho U |
191 | substT rho (Type (s, Ts)) = Type (s, map (typ_subst_nonatomic rho) Ts) |
192 | substT rho (Type (s, Ts)) = Type (s, map (typ_subst_nonatomic rho) Ts) |
192 | substT _ T = T; |
193 | substT _ T = T; |
|
194 |
193 fun force_iter is_rec i TU TU_rec raw_iters = |
195 fun force_iter is_rec i TU TU_rec raw_iters = |
194 let |
196 let |
195 val approx_fold = un_fold_of raw_iters |
197 val approx_fold = un_fold_of raw_iters |
196 |> force_typ names_lthy |
198 |> force_typ names_lthy |
197 (replicate (nth ns i) dummyT ---> (if is_rec then TU_rec else TU)); |
199 (replicate (nth ns i) dummyT ---> (if is_rec then TU_rec else TU)); |
323 |> map (fn thm => thm RS @{thm comp_eq_dest}); |
325 |> map (fn thm => thm RS @{thm comp_eq_dest}); |
324 |
326 |
325 val pre_map_defs = no_refl (map map_def_of_bnf bnfs); |
327 val pre_map_defs = no_refl (map map_def_of_bnf bnfs); |
326 val fp_pre_map_defs = no_refl (map map_def_of_bnf pre_bnfs); |
328 val fp_pre_map_defs = no_refl (map map_def_of_bnf pre_bnfs); |
327 |
329 |
328 val map_unfoldss = map (maps (fn bnf => no_refl [map_def_of_bnf bnf])) pre_bnfss; |
330 val map_unfolds = maps (fn bnf => no_refl [map_def_of_bnf bnf]) pre_bnfs; |
329 val unfold_map = map2 (fn unfs => unfold_thms lthy (id_apply :: unfs)) map_unfoldss; |
331 val unfold_map = map (unfold_thms lthy (id_apply :: map_unfolds)); |
330 |
332 |
331 val fp_xtor_co_iterss = steal #xtor_co_iter_thmss; |
333 val fp_xtor_co_iterss = steal_fp_res #xtor_co_iter_thmss; |
332 val fp_xtor_un_folds = map (mk_pointfree lthy o un_fold_of) fp_xtor_co_iterss |> unfold_map; |
334 val fp_xtor_un_folds = map (mk_pointfree lthy o un_fold_of) fp_xtor_co_iterss |> unfold_map; |
333 val fp_xtor_co_recs = map (mk_pointfree lthy o co_rec_of) fp_xtor_co_iterss |> unfold_map; |
335 val fp_xtor_co_recs = map (mk_pointfree lthy o co_rec_of) fp_xtor_co_iterss |> unfold_map; |
334 |
336 |
335 val fp_co_iter_o_mapss = steal #xtor_co_iter_o_map_thmss; |
337 val fp_co_iter_o_mapss = steal_fp_res #xtor_co_iter_o_map_thmss; |
336 val fp_fold_o_maps = map un_fold_of fp_co_iter_o_mapss |> unfold_map; |
338 val fp_fold_o_maps = map un_fold_of fp_co_iter_o_mapss |> unfold_map; |
337 val fp_rec_o_maps = map co_rec_of fp_co_iter_o_mapss |> unfold_map; |
339 val fp_rec_o_maps = map co_rec_of fp_co_iter_o_mapss |> unfold_map; |
338 val fold_thms = fp_case fp @{thm comp_assoc} @{thm comp_assoc[symmetric]} :: @{thms id_apply |
340 val fold_thms = fp_case fp @{thm comp_assoc} @{thm comp_assoc[symmetric]} :: @{thms id_apply |
339 o_apply comp_id id_comp map_pair.comp map_pair.id sum_map.comp sum_map.id}; |
341 o_apply comp_id id_comp map_pair.comp map_pair.id sum_map.comp sum_map.id}; |
340 val rec_thms = fold_thms @ fp_case fp |
342 val rec_thms = fold_thms @ fp_case fp |
356 |
358 |
357 (* These results are half broken. This is deliberate. We care only about those fields that are |
359 (* These results are half broken. This is deliberate. We care only about those fields that are |
358 used by "primrec", "primcorecursive", and "datatype_compat". *) |
360 used by "primrec", "primcorecursive", and "datatype_compat". *) |
359 val fp_res = |
361 val fp_res = |
360 ({Ts = fpTs, |
362 ({Ts = fpTs, |
361 bnfs = steal #bnfs, |
363 bnfs = steal_fp_res #bnfs, |
362 dtors = dtors, |
364 dtors = dtors, |
363 ctors = ctors, |
365 ctors = ctors, |
364 xtor_co_iterss = transpose [un_folds, co_recs], |
366 xtor_co_iterss = transpose [un_folds, co_recs], |
365 xtor_co_induct = xtor_co_induct_thm, |
367 xtor_co_induct = xtor_co_induct_thm, |
366 dtor_ctors = steal #dtor_ctors (*too general types*), |
368 dtor_ctors = steal_fp_res #dtor_ctors (*too general types*), |
367 ctor_dtors = steal #ctor_dtors (*too general types*), |
369 ctor_dtors = steal_fp_res #ctor_dtors (*too general types*), |
368 ctor_injects = steal #ctor_injects (*too general types*), |
370 ctor_injects = steal_fp_res #ctor_injects (*too general types*), |
369 dtor_injects = steal #dtor_injects (*too general types*), |
371 dtor_injects = steal_fp_res #dtor_injects (*too general types*), |
370 xtor_map_thms = steal #xtor_map_thms (*too general types and terms*), |
372 xtor_map_thms = steal_fp_res #xtor_map_thms (*too general types and terms*), |
371 xtor_set_thmss = steal #xtor_set_thmss (*too general types and terms*), |
373 xtor_set_thmss = steal_fp_res #xtor_set_thmss (*too general types and terms*), |
372 xtor_rel_thms = steal #xtor_rel_thms (*too general types and terms*), |
374 xtor_rel_thms = steal_fp_res #xtor_rel_thms (*too general types and terms*), |
373 xtor_co_iter_thmss = transpose [xtor_un_fold_thms, xtor_co_rec_thms], |
375 xtor_co_iter_thmss = transpose [xtor_un_fold_thms, xtor_co_rec_thms], |
374 xtor_co_iter_o_map_thmss = steal #xtor_co_iter_o_map_thmss (*theorem about old constant*), |
376 xtor_co_iter_o_map_thmss = steal_fp_res #xtor_co_iter_o_map_thmss |
|
377 (*theorem about old constant*), |
375 rel_xtor_co_induct_thm = rel_xtor_co_induct_thm} |
378 rel_xtor_co_induct_thm = rel_xtor_co_induct_thm} |
376 |> morph_fp_result (Morphism.term_morphism "BNF" (singleton (Variable.polymorphic lthy)))); |
379 |> morph_fp_result (Morphism.term_morphism "BNF" (singleton (Variable.polymorphic lthy)))); |
377 in |
380 in |
378 (fp_res, lthy) |
381 (fp_res, lthy) |
379 end; |
382 end; |