126 val ctr_TsssXs = map (map (map freeze_fpXs)) fake_ctr_Tsss; |
126 val ctr_TsssXs = map (map (map freeze_fpXs)) fake_ctr_Tsss; |
127 val sum_prod_TsXs = map (mk_sumTN o map HOLogic.mk_tupleT) ctr_TsssXs; |
127 val sum_prod_TsXs = map (mk_sumTN o map HOLogic.mk_tupleT) ctr_TsssXs; |
128 |
128 |
129 val eqs = map dest_TFree Xs ~~ sum_prod_TsXs; |
129 val eqs = map dest_TFree Xs ~~ sum_prod_TsXs; |
130 |
130 |
131 val ((raw_unfs, raw_flds, raw_fp_iters, raw_fp_recs, unf_flds, fld_unfs, fld_injects), lthy') = |
131 val ((unfs0, flds0, fp_iters0, fp_recs0, unf_flds, fld_unfs, fld_injects), lthy') = |
132 fp_bnf (if gfp then bnf_gfp else bnf_lfp) bs mixfixes As' eqs lthy; |
132 fp_bnf (if gfp then bnf_gfp else bnf_lfp) bs mixfixes As' eqs lthy; |
133 |
133 |
134 val timer = time (Timer.startRealTimer ()); |
134 val timer = time (Timer.startRealTimer ()); |
135 |
135 |
136 fun mk_unf_or_fld get_T Ts t = |
136 fun mk_unf_or_fld get_T Ts t = |
139 end; |
139 end; |
140 |
140 |
141 val mk_unf = mk_unf_or_fld domain_type; |
141 val mk_unf = mk_unf_or_fld domain_type; |
142 val mk_fld = mk_unf_or_fld range_type; |
142 val mk_fld = mk_unf_or_fld range_type; |
143 |
143 |
144 val unfs = map (mk_unf As) raw_unfs; |
144 val unfs = map (mk_unf As) unfs0; |
145 val flds = map (mk_fld As) raw_flds; |
145 val flds = map (mk_fld As) flds0; |
146 |
146 |
147 val fpTs = map (domain_type o fastype_of) unfs; |
147 val fpTs = map (domain_type o fastype_of) unfs; |
148 val ctr_Tsss = map (map (map (Term.typ_subst_atomic (Xs ~~ fpTs)))) ctr_TsssXs; |
148 val ctr_Tsss = map (map (map (Term.typ_subst_atomic (Xs ~~ fpTs)))) ctr_TsssXs; |
149 |
149 |
150 fun mk_fp_iter_or_rec Ts Us c = |
150 val ns = map length ctr_Tsss; |
|
151 val mss = map (map length) ctr_Tsss; |
|
152 val Css = map2 replicate ns Cs; |
|
153 val Cs' = flat Css; |
|
154 |
|
155 fun mk_iter_or_rec Ts Us c = |
151 let |
156 let |
152 val (binders, body) = strip_type (fastype_of c); |
157 val (binders, body) = strip_type (fastype_of c); |
153 val Type (_, Ts0) = if gfp then body else List.last binders; |
158 val (fst_binders, last_binder) = split_last binders; |
154 val Us0 = map (if gfp then domain_type else body_type) (fst (split_last binders)); |
159 val Type (_, Ts0) = if gfp then body else last_binder; |
|
160 val Us0 = map (if gfp then domain_type else body_type) fst_binders; |
155 in |
161 in |
156 Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) c |
162 Term.subst_atomic_types (Ts0 @ Us0 ~~ Ts @ Us) c |
157 end; |
163 end; |
158 |
164 |
159 val fp_iters = map (mk_fp_iter_or_rec As Cs) raw_fp_iters; |
165 val fp_iters = map (mk_iter_or_rec As Cs) fp_iters0; |
160 val fp_recs = map (mk_fp_iter_or_rec As Cs) raw_fp_recs; |
166 val fp_recs = map (mk_iter_or_rec As Cs) fp_recs0; |
161 |
167 |
162 fun pour_sugar_on_type ((((((((((((((b, fpT), C), fld), unf), fp_iter), fp_rec), fld_unf), |
168 fun pour_sugar_on_type ((((((((((((((b, fpT), C), fld), unf), fp_iter), fp_rec), fld_unf), |
163 unf_fld), fld_inject), ctr_binders), ctr_mixfixes), ctr_Tss), disc_binders), sel_binderss) |
169 unf_fld), fld_inject), ctr_binders), ctr_mixfixes), ctr_Tss), disc_binders), sel_binderss) |
164 no_defs_lthy = |
170 no_defs_lthy = |
165 let |
171 let |
197 val phi = Proof_Context.export_morphism lthy lthy'; |
203 val phi = Proof_Context.export_morphism lthy lthy'; |
198 |
204 |
199 val ctr_defs = map (Morphism.thm phi) raw_ctr_defs; |
205 val ctr_defs = map (Morphism.thm phi) raw_ctr_defs; |
200 val case_def = Morphism.thm phi raw_case_def; |
206 val case_def = Morphism.thm phi raw_case_def; |
201 |
207 |
202 val ctrs = map (Morphism.term phi) raw_ctrs; |
208 val ctrs0 = map (Morphism.term phi) raw_ctrs; |
203 val casex = Morphism.term phi raw_case; |
209 val casex0 = Morphism.term phi raw_case; |
|
210 |
|
211 val ctrs = map (mk_ctr As) ctrs0; |
204 |
212 |
205 fun exhaust_tac {context = ctxt, ...} = |
213 fun exhaust_tac {context = ctxt, ...} = |
206 let |
214 let |
207 val fld_iff_unf_thm = |
215 val fld_iff_unf_thm = |
208 let |
216 let |
243 |
251 |
244 (* (co)iterators, (co)recursors, (co)induction *) |
252 (* (co)iterators, (co)recursors, (co)induction *) |
245 |
253 |
246 val is_fpT = member (op =) fpTs; |
254 val is_fpT = member (op =) fpTs; |
247 |
255 |
248 val ns = map length ctr_Tsss; |
|
249 val mss = map (map length) ctr_Tsss; |
|
250 val Css = map2 replicate ns Cs; |
|
251 |
|
252 fun dest_rec_pair (T as Type (@{type_name prod}, Us as [_, U])) = |
256 fun dest_rec_pair (T as Type (@{type_name prod}, Us as [_, U])) = |
253 if member (op =) Cs U then Us else [T] |
257 if member (op =) Cs U then Us else [T] |
254 | dest_rec_pair T = [T]; |
258 | dest_rec_pair T = [T]; |
255 |
259 |
256 fun sugar_datatype no_defs_lthy = |
260 fun sugar_datatype no_defs_lthy = |
301 val phi = Proof_Context.export_morphism lthy lthy'; |
305 val phi = Proof_Context.export_morphism lthy lthy'; |
302 |
306 |
303 val iter_def = Morphism.thm phi raw_iter_def; |
307 val iter_def = Morphism.thm phi raw_iter_def; |
304 val rec_def = Morphism.thm phi raw_rec_def; |
308 val rec_def = Morphism.thm phi raw_rec_def; |
305 |
309 |
306 val iter = Morphism.term phi raw_iter; |
310 val iter0 = Morphism.term phi raw_iter; |
307 val recx = Morphism.term phi raw_rec; |
311 val rec0 = Morphism.term phi raw_rec; |
|
312 |
|
313 val iter = mk_iter_or_rec As Cs' iter0; |
|
314 val recx = mk_iter_or_rec As Cs' rec0; |
308 in |
315 in |
309 ([[ctrs], [[iter]], [[recx]], xss, gss, hss], lthy) |
316 ([[ctrs], [[iter]], [[recx]], xss, gss, hss], lthy) |
310 end; |
317 end; |
311 |
318 |
312 fun sugar_codatatype no_defs_lthy = ([], no_defs_lthy); |
319 fun sugar_codatatype no_defs_lthy = ([], no_defs_lthy); |
313 in |
320 in |
314 wrap_datatype tacss ((ctrs, casex), (disc_binders, sel_binderss)) lthy' |
321 wrap_datatype tacss ((ctrs0, casex0), (disc_binders, sel_binderss)) lthy' |
315 |> (if gfp then sugar_codatatype else sugar_datatype) |
322 |> (if gfp then sugar_codatatype else sugar_datatype) |
316 end; |
323 end; |
317 |
324 |
318 fun pour_more_sugar_on_datatypes ([[ctrss], [[iters]], [[recs]], xsss, gsss, hsss], lthy) = |
325 fun pour_more_sugar_on_datatypes ([[ctrss], [[iters]], [[recs]], xsss, gsss, hsss], lthy) = |
319 let |
326 let |
325 let |
332 let |
326 fun mk_goal_iter_or_rec fc xctr = |
333 fun mk_goal_iter_or_rec fc xctr = |
327 mk_Trueprop_eq (fc $ xctr, fc $ xctr); |
334 mk_Trueprop_eq (fc $ xctr, fc $ xctr); |
328 |
335 |
329 val goal_iterss = map2 (fn giter => map (mk_goal_iter_or_rec giter)) giters xctrss; |
336 val goal_iterss = map2 (fn giter => map (mk_goal_iter_or_rec giter)) giters xctrss; |
330 val goal_recss = []; |
337 val goal_recss = map2 (fn hrec => map (mk_goal_iter_or_rec hrec)) hrecs xctrss; |
331 val iter_tacss = []; (* ### map (map mk_iter_or_rec_tac); (* needs ctr_def, iter_def, fld_iter *) *) |
338 val iter_tacss = |
332 val rec_tacss = []; |
339 map (map (K (fn _ => Skip_Proof.cheat_tac (Proof_Context.theory_of lthy)))) goal_iterss; |
|
340 (* ### map (map mk_iter_or_rec_tac); (* needs ctr_def, iter_def, fld_iter *) *) |
|
341 val rec_tacss = |
|
342 map (map (K (fn _ => Skip_Proof.cheat_tac (Proof_Context.theory_of lthy)))) goal_recss; |
333 in |
343 in |
334 (map2 (map2 (Skip_Proof.prove lthy [] [])) goal_iterss iter_tacss, |
344 (map2 (map2 (Skip_Proof.prove lthy [] [])) goal_iterss iter_tacss, |
335 map2 (map2 (Skip_Proof.prove lthy [] [])) goal_recss rec_tacss) |
345 map2 (map2 (Skip_Proof.prove lthy [] [])) goal_recss rec_tacss) |
336 end; |
346 end; |
337 |
347 |