src/HOL/Codatatype/Tools/bnf_fp_sugar_tactics.ML
changeset 50442 b017e1dbc77c
parent 50441 6d05b8452cf3
child 50443 93f158d59ead
     1.1 --- a/src/HOL/Codatatype/Tools/bnf_fp_sugar_tactics.ML	Mon Sep 17 21:13:30 2012 +0200
     1.2 +++ b/src/HOL/Codatatype/Tools/bnf_fp_sugar_tactics.ML	Mon Sep 17 21:13:30 2012 +0200
     1.3 @@ -43,6 +43,52 @@
     1.4  
     1.5  val inst_spurious_fs_tac = PRIMITIVE o inst_spurious_fs;
     1.6  
     1.7 +fun mk_set_rhs set_lhs T =
     1.8 +  let
     1.9 +    val Type (_, Ts0) = domain_type (fastype_of set_lhs);
    1.10 +    val Type (_, Ts) = domain_type T;
    1.11 +  in
    1.12 +    Term.subst_atomic_types (Ts0 ~~ Ts) set_lhs
    1.13 +  end;
    1.14 +
    1.15 +val mk_fsts_rhs = mk_set_rhs (snd (Logic.dest_equals (prop_of @{thm fsts_def[abs_def]})));
    1.16 +val mk_snds_rhs = mk_set_rhs (snd (Logic.dest_equals (prop_of @{thm snds_def[abs_def]})));
    1.17 +val mk_setl_rhs = mk_set_rhs (snd (Logic.dest_equals (prop_of @{thm sum_setl_def[abs_def]})));
    1.18 +val mk_setr_rhs = mk_set_rhs (snd (Logic.dest_equals (prop_of @{thm sum_setr_def[abs_def]})));
    1.19 +
    1.20 +(* TODO: Put this in "Balanced_Tree" *)
    1.21 +fun balanced_tree_middle n = n div 2;
    1.22 +
    1.23 +val sum_prod_sel_defs =
    1.24 +  @{thms fsts_def[abs_def] snds_def[abs_def] sum_setl_def[abs_def] sum_setr_def[abs_def]};
    1.25 +
    1.26 +fun unfold_sum_prod_sets ctxt ms thm =
    1.27 +  let
    1.28 +    fun unf_prod 0 f = f
    1.29 +      | unf_prod 1 f = f
    1.30 +      | unf_prod m (t1 $ (t2 $ (t3 $ (t4 $ Const (_, T1) $ (t5 $ Const (_, T2) $ t6))))
    1.31 +          $ (t7 $ f $ g)) =
    1.32 +        t1 $ (t2 $ (t3 $ (t4 $ mk_fsts_rhs T1 $ (t5 $ mk_snds_rhs T2 $ t6))))
    1.33 +          $ (t7 $ f $ unf_prod (m - 1) g)
    1.34 +      | unf_prod _ f = f;
    1.35 +    fun unf_sum [m] f = unf_prod m f
    1.36 +      | unf_sum ms (t1 $ (t2 $ (t3 $ (t4 $ Const (_, T1) $ (t5 $ Const (_, T2) $ t6))))
    1.37 +          $ (t7 $ f $ g)) =
    1.38 +        let val (ms1, ms2) = chop (balanced_tree_middle (length ms)) ms in
    1.39 +          t1 $ (t2 $ (t3 $ (t4 $ mk_setl_rhs T1 $ (t5 $ mk_setr_rhs T2 $ t6))))
    1.40 +            $ (t7 $ unf_sum ms1 f $ unf_sum ms2 g)
    1.41 +        end
    1.42 +      | unf_sum _ f = f;
    1.43 +
    1.44 +    val P = prop_of thm;
    1.45 +    val P' = Logic.dest_equals P ||> unf_sum ms;
    1.46 +    val goal = Logic.mk_implies (P, Logic.mk_equals P');
    1.47 +  in
    1.48 +    Skip_Proof.prove ctxt [] [] goal (fn {context = ctxt, ...} =>
    1.49 +      Local_Defs.unfold_tac ctxt sum_prod_sel_defs THEN atac 1)
    1.50 +    OF [thm]
    1.51 +  end;
    1.52 +
    1.53  fun mk_case_tac ctxt n k m case_def ctr_def unf_fld =
    1.54    Local_Defs.unfold_tac ctxt [case_def, ctr_def, unf_fld] THEN
    1.55    (rtac (mk_sum_casesN_balanced n k RS ssubst) THEN'
    1.56 @@ -88,14 +134,14 @@
    1.57    Local_Defs.unfold_tac ctxt @{thms id_def} THEN
    1.58    TRY ((rtac refl ORELSE' subst_tac ctxt @{thms unit_eq} THEN' rtac refl) 1);
    1.59  
    1.60 -(* TODO: Get rid of "auto_tac" (or at least use a naked context) *)
    1.61 +val maybe_singletonI_tac = atac ORELSE' rtac @{thm singletonI};
    1.62  
    1.63 -fun mk_induct_prem_prem_endgame_tac _ 0 = atac ORELSE' rtac @{thm singletonI}
    1.64 +fun mk_induct_prem_prem_endgame_tac _ 0 = maybe_singletonI_tac
    1.65    | mk_induct_prem_prem_endgame_tac ctxt qq =
    1.66      REPEAT_DETERM_N qq o
    1.67 -      (SELECT_GOAL (Local_Defs.unfold_tac ctxt @{thms Union_iff bex_simps(6)}) THEN'
    1.68 -       etac @{thm induct_set_step}) THEN'
    1.69 -    atac ORELSE' SELECT_GOAL (auto_tac ctxt);
    1.70 +      (SELECT_GOAL (Local_Defs.unfold_tac ctxt
    1.71 +         @{thms trans[OF Union_iff bex_simps(6)] mem_compreh_eq_iff ex_mem_singleton}) THEN'
    1.72 +       eresolve_tac @{thms induct_set_step}) THEN' maybe_singletonI_tac;
    1.73  
    1.74  fun gen_UN_comprehI_tac UnI = REPEAT_DETERM o resolve_tac @{thms mem_UN_comprehI} THEN' rtac UnI;
    1.75  
    1.76 @@ -109,19 +155,12 @@
    1.77        image_def o_apply snd_conv snd_prod_fun sum.cases sup_bot_right fst_map_pair map_pair_simp
    1.78        sum_map.simps};
    1.79  
    1.80 -(* These rules interfere with the "set_natural'" properties of "sum" and "prod", so we explicitly
    1.81 -   delay them. *)
    1.82 -val induct_prem_prem_thms_delayed =
    1.83 -  @{thms fsts_def[abs_def] snds_def[abs_def] sum_setl_def[abs_def] sum_setr_def[abs_def]};
    1.84 -
    1.85  fun mk_induct_leverage_prem_prems_tac ctxt nn ppjjqqkks set_natural's pre_set_defs =
    1.86    EVERY' (maps (fn ((pp, jj), (qq, kk)) =>
    1.87      [select_prem_tac nn (dtac meta_spec) kk, etac meta_mp,
    1.88       SELECT_GOAL (Local_Defs.unfold_tac ctxt
    1.89         (pre_set_defs @ set_natural's @ induct_prem_prem_thms)),
    1.90 -     SELECT_GOAL (Local_Defs.unfold_tac ctxt
    1.91 -       (induct_prem_prem_thms_delayed @ induct_prem_prem_thms)),
    1.92 -     gen_UnIN_tac pp jj THEN' mk_induct_prem_prem_endgame_tac ctxt qq]) (rev ppjjqqkks)) 1;
    1.93 +     gen_UnIN_tac pp jj, mk_induct_prem_prem_endgame_tac ctxt qq]) (rev ppjjqqkks)) 1;
    1.94  
    1.95  fun mk_induct_discharge_prem_tac ctxt nn n set_natural's pre_set_defs m k ppjjqqkks =
    1.96    let val r = length ppjjqqkks in
    1.97 @@ -137,10 +176,11 @@
    1.98    let
    1.99      val nn = length ns;
   1.100      val n = Integer.sum ns;
   1.101 +    val pre_set_defss' = map2 (map o unfold_sum_prod_sets ctxt) mss pre_set_defss;
   1.102    in
   1.103      Local_Defs.unfold_tac ctxt ctr_defs THEN rtac fld_induct' 1 THEN inst_spurious_fs_tac ctxt THEN
   1.104      EVERY (map4 (EVERY oooo map3 o mk_induct_discharge_prem_tac ctxt nn n set_natural's)
   1.105 -      pre_set_defss mss (unflat mss (1 upto n)) ppjjqqkksss)
   1.106 +      pre_set_defss' mss (unflat mss (1 upto n)) ppjjqqkksss)
   1.107    end;
   1.108  
   1.109  end;