src/HOL/Tools/BNF/bnf_fp_def_sugar_tactics.ML
changeset 58634 9f10d82e8188
parent 58507 ce0b9be06f85
child 58676 cdf84b6e1297
equal deleted inserted replaced
58633:8529745af3dc 58634:9f10d82e8188
   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 @