139 HEADGOAL (EVERY' (maps (fn k => [select_prem_tac n (rotate_tac 1) k, |
139 HEADGOAL (EVERY' (maps (fn k => [select_prem_tac n (rotate_tac 1) k, |
140 REPEAT_DETERM o dtac meta_spec, etac meta_mp, atac]) (1 upto n))); |
140 REPEAT_DETERM o dtac meta_spec, etac meta_mp, atac]) (1 upto n))); |
141 |
141 |
142 fun mk_ctor_iff_dtor_tac ctxt cTs cctor cdtor ctor_dtor dtor_ctor = |
142 fun mk_ctor_iff_dtor_tac ctxt cTs cctor cdtor ctor_dtor dtor_ctor = |
143 HEADGOAL (rtac iffI THEN' |
143 HEADGOAL (rtac iffI THEN' |
144 EVERY' (map3 (fn cTs => fn cx => fn th => |
144 EVERY' (@{map 3} (fn cTs => fn cx => fn th => |
145 dtac (Drule.instantiate' cTs [NONE, NONE, SOME cx] arg_cong) THEN' |
145 dtac (Drule.instantiate' cTs [NONE, NONE, SOME cx] arg_cong) THEN' |
146 SELECT_GOAL (unfold_thms_tac ctxt [th]) THEN' |
146 SELECT_GOAL (unfold_thms_tac ctxt [th]) THEN' |
147 atac) [rev cTs, cTs] [cdtor, cctor] [dtor_ctor, ctor_dtor])); |
147 atac) [rev cTs, cTs] [cdtor, cctor] [dtor_ctor, ctor_dtor])); |
148 |
148 |
149 fun mk_half_distinct_tac ctxt ctor_inject abs_inject ctr_defs = |
149 fun mk_half_distinct_tac ctxt ctor_inject abs_inject ctr_defs = |
210 HEADGOAL (rtac (ctor_dtor_corec RS trans) THEN' asm_simp_tac ss) THEN_MAYBE |
210 HEADGOAL (rtac (ctor_dtor_corec RS trans) THEN' asm_simp_tac ss) THEN_MAYBE |
211 HEADGOAL (rtac refl ORELSE' rtac (@{thm unit_eq} RS arg_cong)) |
211 HEADGOAL (rtac refl ORELSE' rtac (@{thm unit_eq} RS arg_cong)) |
212 end; |
212 end; |
213 |
213 |
214 fun mk_corec_disc_iff_tac case_splits' corecs discs ctxt = |
214 fun mk_corec_disc_iff_tac case_splits' corecs discs ctxt = |
215 EVERY (map3 (fn case_split_tac => fn corec_thm => fn disc => |
215 EVERY (@{map 3} (fn case_split_tac => fn corec_thm => fn disc => |
216 HEADGOAL case_split_tac THEN unfold_thms_tac ctxt [corec_thm] THEN |
216 HEADGOAL case_split_tac THEN unfold_thms_tac ctxt [corec_thm] THEN |
217 HEADGOAL (asm_simp_tac (ss_only basic_simp_thms ctxt)) THEN |
217 HEADGOAL (asm_simp_tac (ss_only basic_simp_thms ctxt)) THEN |
218 (if is_refl disc then all_tac else HEADGOAL (rtac disc))) |
218 (if is_refl disc then all_tac else HEADGOAL (rtac disc))) |
219 (map rtac case_splits' @ [K all_tac]) corecs discs); |
219 (map rtac case_splits' @ [K all_tac]) corecs discs); |
220 |
220 |
275 unfold_thms_tac ctxt (rel_pre_T_defs @ rel_eqs) |
275 unfold_thms_tac ctxt (rel_pre_T_defs @ rel_eqs) |
276 end; |
276 end; |
277 |
277 |
278 fun mk_unfold_prop_tac dtor_corec_transfer corec_def = |
278 fun mk_unfold_prop_tac dtor_corec_transfer corec_def = |
279 mk_unfold_corec_type_tac dtor_corec_transfer corec_def THEN |
279 mk_unfold_corec_type_tac dtor_corec_transfer corec_def THEN |
280 EVERY (map4 mk_unfold_type_tac type_definitions pss qssss gssss); |
280 EVERY (@{map 4} mk_unfold_type_tac type_definitions pss qssss gssss); |
281 in |
281 in |
282 HEADGOAL Goal.conjunction_tac THEN |
282 HEADGOAL Goal.conjunction_tac THEN |
283 EVERY (map2 mk_unfold_prop_tac dtor_corec_transfers corec_defs) |
283 EVERY (map2 mk_unfold_prop_tac dtor_corec_transfers corec_defs) |
284 end; |
284 end; |
285 |
285 |
313 (if exists is_def_looping ctr_defs then |
313 (if exists is_def_looping ctr_defs then |
314 EVERY (map (fn def => HEADGOAL (subst_asm_tac ctxt NONE [def])) ctr_defs) |
314 EVERY (map (fn def => HEADGOAL (subst_asm_tac ctxt NONE [def])) ctr_defs) |
315 else |
315 else |
316 unfold_thms_tac ctxt ctr_defs) THEN |
316 unfold_thms_tac ctxt ctr_defs) THEN |
317 HEADGOAL (rtac ctor_induct') THEN co_induct_inst_as_projs_tac ctxt 0 THEN |
317 HEADGOAL (rtac ctor_induct') THEN co_induct_inst_as_projs_tac ctxt 0 THEN |
318 EVERY (map4 (EVERY oooo map3 o |
318 EVERY (@{map 4} (EVERY oooo @{map 3} o |
319 mk_induct_discharge_prem_tac ctxt nn n fp_abs_inverses abs_inverses set_maps) |
319 mk_induct_discharge_prem_tac ctxt nn n fp_abs_inverses abs_inverses set_maps) |
320 pre_set_defss mss (unflat mss (1 upto n)) kkss) |
320 pre_set_defss mss (unflat mss (1 upto n)) kkss) |
321 end; |
321 end; |
322 |
322 |
323 fun mk_coinduct_same_ctr_tac ctxt rel_eqs pre_rel_def fp_abs_inverse abs_inverse dtor_ctor ctr_def |
323 fun mk_coinduct_same_ctr_tac ctxt rel_eqs pre_rel_def fp_abs_inverse abs_inverse dtor_ctor ctr_def |
346 dtor_ctor exhaust ctr_defs discss selss = |
346 dtor_ctor exhaust ctr_defs discss selss = |
347 let val ks = 1 upto n in |
347 let val ks = 1 upto n in |
348 EVERY' ([rtac allI, rtac allI, rtac impI, select_prem_tac nn (dtac meta_spec) kk, |
348 EVERY' ([rtac allI, rtac allI, rtac impI, select_prem_tac nn (dtac meta_spec) kk, |
349 dtac meta_spec, dtac meta_mp, atac, rtac exhaust, K (co_induct_inst_as_projs_tac ctxt 0), |
349 dtac meta_spec, dtac meta_mp, atac, rtac exhaust, K (co_induct_inst_as_projs_tac ctxt 0), |
350 hyp_subst_tac ctxt] @ |
350 hyp_subst_tac ctxt] @ |
351 map4 (fn k => fn ctr_def => fn discs => fn sels => |
351 @{map 4} (fn k => fn ctr_def => fn discs => fn sels => |
352 EVERY' ([rtac exhaust, K (co_induct_inst_as_projs_tac ctxt 1)] @ |
352 EVERY' ([rtac exhaust, K (co_induct_inst_as_projs_tac ctxt 1)] @ |
353 map2 (fn k' => fn discs' => |
353 map2 (fn k' => fn discs' => |
354 if k' = k then |
354 if k' = k then |
355 mk_coinduct_same_ctr_tac ctxt rel_eqs' pre_rel_def fp_abs_inverse abs_inverse |
355 mk_coinduct_same_ctr_tac ctxt rel_eqs' pre_rel_def fp_abs_inverse abs_inverse |
356 dtor_ctor ctr_def discs sels |
356 dtor_ctor ctr_def discs sels |
359 end; |
359 end; |
360 |
360 |
361 fun mk_coinduct_tac ctxt rel_eqs' nn ns dtor_coinduct' pre_rel_defs fp_abs_inverses abs_inverses |
361 fun mk_coinduct_tac ctxt rel_eqs' nn ns dtor_coinduct' pre_rel_defs fp_abs_inverses abs_inverses |
362 dtor_ctors exhausts ctr_defss discsss selsss = |
362 dtor_ctors exhausts ctr_defss discsss selsss = |
363 HEADGOAL (rtac dtor_coinduct' THEN' |
363 HEADGOAL (rtac dtor_coinduct' THEN' |
364 EVERY' (map10 (mk_coinduct_discharge_prem_tac ctxt rel_eqs' nn) |
364 EVERY' (@{map 10} (mk_coinduct_discharge_prem_tac ctxt rel_eqs' nn) |
365 (1 upto nn) ns pre_rel_defs fp_abs_inverses abs_inverses dtor_ctors exhausts ctr_defss discsss |
365 (1 upto nn) ns pre_rel_defs fp_abs_inverses abs_inverses dtor_ctors exhausts ctr_defss discsss |
366 selsss)); |
366 selsss)); |
367 |
367 |
368 fun mk_map_disc_iff_tac ctxt ct exhaust discs maps = |
368 fun mk_map_disc_iff_tac ctxt ct exhaust discs maps = |
369 TRYALL Goal.conjunction_tac THEN |
369 TRYALL Goal.conjunction_tac THEN |
399 REPEAT_DETERM o (dtac @{thm meta_mp} THEN' rtac refl) THEN' Goal.assume_rule_tac ctxt)); |
399 REPEAT_DETERM o (dtac @{thm meta_mp} THEN' rtac refl) THEN' Goal.assume_rule_tac ctxt)); |
400 |
400 |
401 fun mk_rel_coinduct0_tac ctxt dtor_rel_coinduct cts assms exhausts discss selss ctor_defss |
401 fun mk_rel_coinduct0_tac ctxt dtor_rel_coinduct cts assms exhausts discss selss ctor_defss |
402 dtor_ctors ctor_injects abs_injects rel_pre_defs abs_inverses nesting_rel_eqs = |
402 dtor_ctors ctor_injects abs_injects rel_pre_defs abs_inverses nesting_rel_eqs = |
403 rtac dtor_rel_coinduct 1 THEN |
403 rtac dtor_rel_coinduct 1 THEN |
404 EVERY (map11 (fn ct => fn assm => fn exhaust => fn discs => fn sels => fn ctor_defs => |
404 EVERY (@{map 11} (fn ct => fn assm => fn exhaust => fn discs => fn sels => fn ctor_defs => |
405 fn dtor_ctor => fn ctor_inject => fn abs_inject => fn rel_pre_def => fn abs_inverse => |
405 fn dtor_ctor => fn ctor_inject => fn abs_inject => fn rel_pre_def => fn abs_inverse => |
406 (rtac exhaust THEN_ALL_NEW (rtac exhaust THEN_ALL_NEW |
406 (rtac exhaust THEN_ALL_NEW (rtac exhaust THEN_ALL_NEW |
407 (dtac (rotate_prems ~1 (cterm_instantiate_pos [NONE, NONE, NONE, NONE, SOME ct] |
407 (dtac (rotate_prems ~1 (cterm_instantiate_pos [NONE, NONE, NONE, NONE, SOME ct] |
408 @{thm arg_cong2} RS iffD1)) THEN' |
408 @{thm arg_cong2} RS iffD1)) THEN' |
409 atac THEN' atac THEN' hyp_subst_tac ctxt THEN' dtac assm THEN' |
409 atac THEN' atac THEN' hyp_subst_tac ctxt THEN' dtac assm THEN' |
418 cts assms exhausts discss selss ctor_defss dtor_ctors ctor_injects abs_injects rel_pre_defs |
418 cts assms exhausts discss selss ctor_defss dtor_ctors ctor_injects abs_injects rel_pre_defs |
419 abs_inverses); |
419 abs_inverses); |
420 |
420 |
421 fun mk_rel_induct0_tac ctxt ctor_rel_induct assms cterms exhausts ctor_defss ctor_injects |
421 fun mk_rel_induct0_tac ctxt ctor_rel_induct assms cterms exhausts ctor_defss ctor_injects |
422 rel_pre_list_defs Abs_inverses nesting_rel_eqs = |
422 rel_pre_list_defs Abs_inverses nesting_rel_eqs = |
423 rtac ctor_rel_induct 1 THEN EVERY (map6 (fn cterm => fn exhaust => fn ctor_defs => |
423 rtac ctor_rel_induct 1 THEN EVERY (@{map 6} (fn cterm => fn exhaust => fn ctor_defs => |
424 fn ctor_inject => fn rel_pre_list_def => fn Abs_inverse => |
424 fn ctor_inject => fn rel_pre_list_def => fn Abs_inverse => |
425 HEADGOAL (rtac exhaust THEN_ALL_NEW (rtac exhaust THEN_ALL_NEW |
425 HEADGOAL (rtac exhaust THEN_ALL_NEW (rtac exhaust THEN_ALL_NEW |
426 (rtac (cterm_instantiate_pos (replicate 4 NONE @ [SOME cterm]) @{thm arg_cong2} RS iffD2) |
426 (rtac (cterm_instantiate_pos (replicate 4 NONE @ [SOME cterm]) @{thm arg_cong2} RS iffD2) |
427 THEN' atac THEN' atac THEN' TRY o resolve_tac assms))) THEN |
427 THEN' atac THEN' atac THEN' TRY o resolve_tac assms))) THEN |
428 unfold_thms_tac ctxt (ctor_inject :: rel_pre_list_def :: ctor_defs @ nesting_rel_eqs @ |
428 unfold_thms_tac ctxt (ctor_inject :: rel_pre_list_def :: ctor_defs @ nesting_rel_eqs @ |