src/HOL/Codatatype/Tools/bnf_fp_sugar_tactics.ML
changeset 50383 df359ce891ac
parent 50378 8fc53d925629
child 50385 be6e749fd003
     1.1 --- a/src/HOL/Codatatype/Tools/bnf_fp_sugar_tactics.ML	Fri Sep 14 12:09:27 2012 +0200
     1.2 +++ b/src/HOL/Codatatype/Tools/bnf_fp_sugar_tactics.ML	Fri Sep 14 12:09:27 2012 +0200
     1.3 @@ -13,7 +13,8 @@
     1.4    val mk_fld_iff_unf_tac: Proof.context -> ctyp option list -> cterm -> cterm -> thm -> thm
     1.5      -> tactic
     1.6    val mk_half_distinct_tac: Proof.context -> thm -> thm list -> tactic
     1.7 -  val mk_induct_tac: Proof.context -> tactic
     1.8 +  val mk_induct_tac: Proof.context -> int list -> int list list -> int list list -> thm list ->
     1.9 +    thm -> thm list list -> thm list -> tactic
    1.10    val mk_inject_tac: Proof.context -> thm -> thm -> tactic
    1.11    val mk_iter_like_tac: thm list -> thm list -> thm list -> thm -> thm -> Proof.context -> tactic
    1.12  end;
    1.13 @@ -25,6 +26,23 @@
    1.14  open BNF_Util
    1.15  open BNF_FP_Util
    1.16  
    1.17 +val meta_mp = @{thm meta_mp};
    1.18 +val meta_spec = @{thm meta_spec};
    1.19 +
    1.20 +fun squash_spurious_fs lthy thm =
    1.21 +  let
    1.22 +    val spurious_fs =
    1.23 +      Term.add_vars (prop_of thm) []
    1.24 +      |> filter (fn (_, Type (@{type_name fun}, [_, T'])) => T' <> HOLogic.boolT | _ => false);
    1.25 +    val cxs =
    1.26 +      map (fn s as (_, T) =>
    1.27 +        (certify lthy (Var s), certify lthy (id_abs (domain_type T)))) spurious_fs;
    1.28 +  in
    1.29 +    Drule.cterm_instantiate cxs thm
    1.30 +  end;
    1.31 +
    1.32 +val squash_spurious_fs_tac = PRIMITIVE o squash_spurious_fs;
    1.33 +
    1.34  fun mk_case_tac ctxt n k m case_def ctr_def unf_fld =
    1.35    Local_Defs.unfold_tac ctxt [case_def, ctr_def, unf_fld] THEN
    1.36    (rtac (mk_sum_casesN_balanced n k RS ssubst) THEN'
    1.37 @@ -34,8 +52,8 @@
    1.38  fun mk_exhaust_tac ctxt n ctr_defs fld_iff_unf sumEN' =
    1.39    Local_Defs.unfold_tac ctxt (fld_iff_unf :: ctr_defs) THEN rtac sumEN' 1 THEN
    1.40    Local_Defs.unfold_tac ctxt @{thms all_prod_eq} THEN
    1.41 -  EVERY' (maps (fn k => [select_prem_tac n (rotate_tac 1) k, REPEAT_DETERM o dtac @{thm meta_spec},
    1.42 -    etac @{thm meta_mp}, atac]) (1 upto n)) 1;
    1.43 +  EVERY' (maps (fn k => [select_prem_tac n (rotate_tac 1) k, REPEAT_DETERM o dtac meta_spec,
    1.44 +    etac meta_mp, atac]) (1 upto n)) 1;
    1.45  
    1.46  fun mk_fld_iff_unf_tac ctxt cTs cfld cunf fld_unf unf_fld =
    1.47    (rtac iffI THEN'
    1.48 @@ -52,9 +70,6 @@
    1.49    Local_Defs.unfold_tac ctxt [ctr_def] THEN rtac (fld_inject RS ssubst) 1 THEN
    1.50    Local_Defs.unfold_tac ctxt @{thms sum.inject Pair_eq conj_assoc} THEN rtac refl 1;
    1.51  
    1.52 -fun mk_induct_tac ctxt =
    1.53 -  Skip_Proof.cheat_tac (Proof_Context.theory_of ctxt) (* FIXME: TODO *);
    1.54 -
    1.55  val iter_like_thms =
    1.56    @{thms case_unit comp_def convol_def id_apply map_pair_def sum.simps(5,6) sum_map.simps
    1.57        split_conv};
    1.58 @@ -73,4 +88,52 @@
    1.59    Local_Defs.unfold_tac ctxt @{thms id_def} THEN
    1.60    TRY ((rtac refl ORELSE' subst_tac ctxt @{thms unit_eq} THEN' rtac refl) 1);
    1.61  
    1.62 +fun mk_induct_prelude_tac ctxt ctr_defs fld_induct' =
    1.63 +  Local_Defs.unfold_tac ctxt ctr_defs THEN rtac fld_induct' 1 THEN squash_spurious_fs_tac ctxt;
    1.64 +
    1.65 +fun mk_induct_prepare_prem_tac n m k =
    1.66 +  EVERY' [select_prem_tac n (rotate_tac 1) k, rotate_tac ~1, hyp_subst_tac,
    1.67 +    REPEAT_DETERM_N m o (dtac meta_spec THEN' rotate_tac ~1)] 1;
    1.68 +
    1.69 +fun mk_induct_prepare_prem_prems_tac _ _ 0 = all_tac
    1.70 +  | mk_induct_prepare_prem_prems_tac nn kk r =
    1.71 +    REPEAT_DETERM_N r (rotate_tac (~1 + kk - nn) 1 THEN dtac meta_mp 1 THEN
    1.72 +      defer_tac 2 THEN PRIMITIVE (Thm.permute_prems 0 ~1) THEN rotate_tac 1 1) THEN
    1.73 +    PRIMITIVE Raw_Simplifier.norm_hhf;
    1.74 +
    1.75 +val induct_prem_prem_thms =
    1.76 +  @{thms SUP_empty Sup_empty Sup_insert UN_compreh_bex UN_insert Un_assoc[symmetric] Un_empty_left
    1.77 +      Un_empty_right Union_Un_distrib collect_def[abs_def] fst_conv fsts_def[abs_def] image_def
    1.78 +      map_pair_simp o_apply snd_conv snds_def[abs_def] sum.cases sum_map.simps sum_setl_def[abs_def]
    1.79 +      sum_setr_def[abs_def] sup_bot_right};
    1.80 +
    1.81 +fun mk_induct_discharge_prem_prems_tac ctxt r pre_set_defs set_natural's =
    1.82 +  EVERY' (maps (fn i =>
    1.83 +    [dtac meta_spec, rotate_tac ~1, etac meta_mp,
    1.84 +     SELECT_GOAL (Local_Defs.unfold_tac ctxt
    1.85 +       (set_natural's @ pre_set_defs @ induct_prem_prem_thms)),
    1.86 +     rtac (mk_UnIN r i),
    1.87 +     atac ORELSE'
    1.88 +     rtac @{thm singletonI} ORELSE'
    1.89 +     (REPEAT_DETERM o (atac ORELSE'
    1.90 +        SELECT_GOAL (Local_Defs.unfold_tac ctxt @{thms Union_iff bex_simps(6)}) THEN'
    1.91 +        etac @{thm induct_set_step}))]) (r downto 1)) 1;
    1.92 +
    1.93 +fun mk_induct_discharge_prem_tac ctxt nn kk n m k r pre_set_defs set_natural's =
    1.94 +  EVERY [mk_induct_prepare_prem_tac n m k,
    1.95 +    mk_induct_prepare_prem_prems_tac nn kk r, atac 1,
    1.96 +    mk_induct_discharge_prem_prems_tac ctxt r pre_set_defs set_natural's];
    1.97 +
    1.98 +fun mk_induct_tac ctxt ns mss rss ctr_defs fld_induct' pre_set_defss set_natural's =
    1.99 +  let
   1.100 +    val nn = length ns;
   1.101 +    val n = Integer.sum ns;
   1.102 +  in
   1.103 +    mk_induct_prelude_tac ctxt ctr_defs fld_induct' THEN
   1.104 +    EVERY (map5 (fn kk => fn pre_set_defs =>
   1.105 +        EVERY ooo map3 (fn m => fn k => fn r =>
   1.106 +            mk_induct_discharge_prem_tac ctxt nn kk n m k r pre_set_defs set_natural's))
   1.107 +      (1 upto nn) pre_set_defss mss (unflat mss (1 upto Integer.sum ns)) rss)
   1.108 +  end;
   1.109 +
   1.110  end;