166 val ns = map length ctr_Tsss; |
195 val ns = map length ctr_Tsss; |
167 val kss = map (fn n => 1 upto n) ns; |
196 val kss = map (fn n => 1 upto n) ns; |
168 val mss = map (map length) ctr_Tsss; |
197 val mss = map (map length) ctr_Tsss; |
169 |
198 |
170 val fp_eqs = map dest_TFree Xs ~~ ctrXs_sum_prod_Ts; |
199 val fp_eqs = map dest_TFree Xs ~~ ctrXs_sum_prod_Ts; |
171 |
200 val key = key_of_fp_eqs fp fpTs fp_eqs; |
172 val base_fp_names = Name.variant_list [] fp_b_names; |
|
173 val fp_bs = map2 (fn b_name => fn base_fp_name => |
|
174 Binding.qualify true b_name (Binding.name (n2mN ^ base_fp_name))) |
|
175 b_names base_fp_names; |
|
176 |
|
177 val (pre_bnfs, (fp_res as {xtor_co_iterss = xtor_co_iterss0, xtor_co_induct, |
|
178 dtor_injects, dtor_ctors, xtor_co_iter_thmss, ...}, lthy)) = |
|
179 fp_bnf (construct_mutualized_fp fp fpTs fp_sugars0) fp_bs As' fp_eqs no_defs_lthy; |
|
180 |
|
181 val nesting_bnfs = nesty_bnfs lthy ctrXs_Tsss As; |
|
182 val nested_bnfs = nesty_bnfs lthy ctrXs_Tsss Xs; |
|
183 |
|
184 val ((xtor_co_iterss, iters_args_types, coiters_args_types), _) = |
|
185 mk_co_iters_prelims fp ctr_Tsss fpTs Cs ns mss xtor_co_iterss0 lthy; |
|
186 |
|
187 fun mk_binding b suf = Binding.suffix_name ("_" ^ suf) b; |
|
188 |
|
189 val ((co_iterss, co_iter_defss), lthy) = |
|
190 fold_map2 (fn b => |
|
191 (if fp = Least_FP then define_iters [foldN, recN] (the iters_args_types) |
|
192 else define_coiters [unfoldN, corecN] (the coiters_args_types)) |
|
193 (mk_binding b) fpTs Cs) fp_bs xtor_co_iterss lthy |
|
194 |>> split_list; |
|
195 |
|
196 val rho = tvar_subst thy Ts fpTs; |
|
197 val ctr_sugar_phi = |
|
198 Morphism.compose (Morphism.typ_morphism (Term.typ_subst_TVars rho)) |
|
199 (Morphism.term_morphism (Term.subst_TVars rho)); |
|
200 val inst_ctr_sugar = morph_ctr_sugar ctr_sugar_phi; |
|
201 |
|
202 val ctr_sugars = map inst_ctr_sugar ctr_sugars0; |
|
203 |
|
204 val ((co_inducts, un_fold_thmss, co_rec_thmss, disc_unfold_thmss, disc_corec_thmss, |
|
205 sel_unfold_thmsss, sel_corec_thmsss), fp_sugar_thms) = |
|
206 if fp = Least_FP then |
|
207 derive_induct_iters_thms_for_types pre_bnfs (the iters_args_types) xtor_co_induct |
|
208 xtor_co_iter_thmss nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss ctrss ctr_defss |
|
209 co_iterss co_iter_defss lthy |
|
210 |> `(fn ((_, induct, _), (fold_thmss, rec_thmss, _)) => |
|
211 ([induct], fold_thmss, rec_thmss, [], [], [], [])) |
|
212 ||> (fn info => (SOME info, NONE)) |
|
213 else |
|
214 derive_coinduct_coiters_thms_for_types pre_bnfs (the coiters_args_types) xtor_co_induct |
|
215 dtor_injects dtor_ctors xtor_co_iter_thmss nesting_bnfs fpTs Cs Xs ctrXs_Tsss kss mss ns |
|
216 ctr_defss ctr_sugars co_iterss co_iter_defss (Proof_Context.export lthy no_defs_lthy) |
|
217 lthy |
|
218 |> `(fn ((coinduct_thms_pairs, _), (unfold_thmss, corec_thmss, _), |
|
219 (disc_unfold_thmss, disc_corec_thmss, _), _, |
|
220 (sel_unfold_thmsss, sel_corec_thmsss, _)) => |
|
221 (map snd coinduct_thms_pairs, unfold_thmss, corec_thmss, disc_unfold_thmss, |
|
222 disc_corec_thmss, sel_unfold_thmsss, sel_corec_thmsss)) |
|
223 ||> (fn info => (NONE, SOME info)); |
|
224 |
|
225 val phi = Proof_Context.export_morphism no_defs_lthy no_defs_lthy0; |
|
226 |
|
227 fun mk_target_fp_sugar (kk, T) = |
|
228 {T = T, fp = fp, index = kk, pre_bnfs = pre_bnfs, nested_bnfs = nested_bnfs, |
|
229 nesting_bnfs = nesting_bnfs, fp_res = fp_res, ctr_defss = ctr_defss, |
|
230 ctr_sugars = ctr_sugars, co_iterss = co_iterss, mapss = mapss, co_inducts = co_inducts, |
|
231 co_iter_thmsss = transpose [un_fold_thmss, co_rec_thmss], |
|
232 disc_co_itersss = transpose [disc_unfold_thmss, disc_corec_thmss], |
|
233 sel_co_iterssss = transpose [sel_unfold_thmsss, sel_corec_thmsss]} |
|
234 |> morph_fp_sugar phi; |
|
235 in |
201 in |
236 ((map_index mk_target_fp_sugar fpTs, fp_sugar_thms), lthy) |
202 (case n2m_sugar_of no_defs_lthy key of |
|
203 SOME n2m_sugar => (n2m_sugar, no_defs_lthy) |
|
204 | NONE => |
|
205 let |
|
206 val base_fp_names = Name.variant_list [] fp_b_names; |
|
207 val fp_bs = map2 (fn b_name => fn base_fp_name => |
|
208 Binding.qualify true b_name (Binding.name (n2mN ^ base_fp_name))) |
|
209 b_names base_fp_names; |
|
210 |
|
211 val (pre_bnfs, (fp_res as {xtor_co_iterss = xtor_co_iterss0, xtor_co_induct, |
|
212 dtor_injects, dtor_ctors, xtor_co_iter_thmss, ...}, lthy)) = |
|
213 fp_bnf (construct_mutualized_fp fp fpTs fp_sugars0) fp_bs As' fp_eqs no_defs_lthy; |
|
214 |
|
215 val nesting_bnfs = nesty_bnfs lthy ctrXs_Tsss As; |
|
216 val nested_bnfs = nesty_bnfs lthy ctrXs_Tsss Xs; |
|
217 |
|
218 val ((xtor_co_iterss, iters_args_types, coiters_args_types), _) = |
|
219 mk_co_iters_prelims fp ctr_Tsss fpTs Cs ns mss xtor_co_iterss0 lthy; |
|
220 |
|
221 fun mk_binding b suf = Binding.suffix_name ("_" ^ suf) b; |
|
222 |
|
223 val ((co_iterss, co_iter_defss), lthy) = |
|
224 fold_map2 (fn b => |
|
225 (if fp = Least_FP then define_iters [foldN, recN] (the iters_args_types) |
|
226 else define_coiters [unfoldN, corecN] (the coiters_args_types)) |
|
227 (mk_binding b) fpTs Cs) fp_bs xtor_co_iterss lthy |
|
228 |>> split_list; |
|
229 |
|
230 val rho = tvar_subst thy Ts fpTs; |
|
231 val ctr_sugar_phi = |
|
232 Morphism.compose (Morphism.typ_morphism (Term.typ_subst_TVars rho)) |
|
233 (Morphism.term_morphism (Term.subst_TVars rho)); |
|
234 val inst_ctr_sugar = morph_ctr_sugar ctr_sugar_phi; |
|
235 |
|
236 val ctr_sugars = map inst_ctr_sugar ctr_sugars0; |
|
237 |
|
238 val ((co_inducts, un_fold_thmss, co_rec_thmss, disc_unfold_thmss, disc_corec_thmss, |
|
239 sel_unfold_thmsss, sel_corec_thmsss), fp_sugar_thms) = |
|
240 if fp = Least_FP then |
|
241 derive_induct_iters_thms_for_types pre_bnfs (the iters_args_types) xtor_co_induct |
|
242 xtor_co_iter_thmss nesting_bnfs nested_bnfs fpTs Cs Xs ctrXs_Tsss ctrss ctr_defss |
|
243 co_iterss co_iter_defss lthy |
|
244 |> `(fn ((_, induct, _), (fold_thmss, rec_thmss, _)) => |
|
245 ([induct], fold_thmss, rec_thmss, [], [], [], [])) |
|
246 ||> (fn info => (SOME info, NONE)) |
|
247 else |
|
248 derive_coinduct_coiters_thms_for_types pre_bnfs (the coiters_args_types) |
|
249 xtor_co_induct dtor_injects dtor_ctors xtor_co_iter_thmss nesting_bnfs fpTs Cs Xs |
|
250 ctrXs_Tsss kss mss ns ctr_defss ctr_sugars co_iterss co_iter_defss |
|
251 (Proof_Context.export lthy no_defs_lthy) lthy |
|
252 |> `(fn ((coinduct_thms_pairs, _), (unfold_thmss, corec_thmss, _), |
|
253 (disc_unfold_thmss, disc_corec_thmss, _), _, |
|
254 (sel_unfold_thmsss, sel_corec_thmsss, _)) => |
|
255 (map snd coinduct_thms_pairs, unfold_thmss, corec_thmss, disc_unfold_thmss, |
|
256 disc_corec_thmss, sel_unfold_thmsss, sel_corec_thmsss)) |
|
257 ||> (fn info => (NONE, SOME info)); |
|
258 |
|
259 val phi = Proof_Context.export_morphism no_defs_lthy no_defs_lthy0; |
|
260 |
|
261 fun mk_target_fp_sugar (kk, T) = |
|
262 {T = T, fp = fp, index = kk, pre_bnfs = pre_bnfs, nested_bnfs = nested_bnfs, |
|
263 nesting_bnfs = nesting_bnfs, fp_res = fp_res, ctr_defss = ctr_defss, |
|
264 ctr_sugars = ctr_sugars, co_iterss = co_iterss, mapss = mapss, co_inducts = co_inducts, |
|
265 co_iter_thmsss = transpose [un_fold_thmss, co_rec_thmss], |
|
266 disc_co_itersss = transpose [disc_unfold_thmss, disc_corec_thmss], |
|
267 sel_co_iterssss = transpose [sel_unfold_thmsss, sel_corec_thmsss]} |
|
268 |> morph_fp_sugar phi; |
|
269 |
|
270 val n2m_sugar = (map_index mk_target_fp_sugar fpTs, fp_sugar_thms); |
|
271 in |
|
272 (n2m_sugar, lthy |> register_n2m_sugar key n2m_sugar) |
|
273 end) |
237 end |
274 end |
238 else |
275 else |
239 (* TODO: reorder hypotheses and predicates in (co)induction rules? *) |
|
240 ((fp_sugars0, (NONE, NONE)), no_defs_lthy0); |
276 ((fp_sugars0, (NONE, NONE)), no_defs_lthy0); |
241 |
277 |
242 fun indexify_callsss fp_sugar callsss = |
278 fun indexify_callsss fp_sugar callsss = |
243 let |
279 let |
244 val {ctrs, ...} = of_fp_sugar #ctr_sugars fp_sugar; |
280 val {ctrs, ...} = of_fp_sugar #ctr_sugars fp_sugar; |