handle the general case with more than two levels of nesting when discharging induction prem prems
authorblanchet
Mon, 17 Sep 2012 21:13:30 +0200
changeset 5044393f158d59ead
parent 50442 b017e1dbc77c
child 50444 64ac3471005a
handle the general case with more than two levels of nesting when discharging induction prem prems
src/HOL/Codatatype/BNF_FP.thy
src/HOL/Codatatype/Tools/bnf_fp_sugar_tactics.ML
     1.1 --- a/src/HOL/Codatatype/BNF_FP.thy	Mon Sep 17 21:13:30 2012 +0200
     1.2 +++ b/src/HOL/Codatatype/BNF_FP.thy	Mon Sep 17 21:13:30 2012 +0200
     1.3 @@ -123,8 +123,15 @@
     1.4  "\<exists>y. (\<exists>x\<in>A. y = F x) \<and> z \<in> y \<Longrightarrow> z \<in> \<Union>{y. \<exists>x\<in>A. y = {y. \<exists>y'\<in>F x. y = y'}}"
     1.5  by blast
     1.6  
     1.7 +lemma mem_UN_compreh_eq: "(z : \<Union>{y. \<exists>x\<in>A. y = F x}) = (\<exists>x\<in>A. z : F x)"
     1.8 +by blast
     1.9 +
    1.10 +lemma eq_UN_compreh_Un: "(xa = \<Union>{y. \<exists>x\<in>A. y = c_set1 x \<union> c_set2 x}) =
    1.11 +  (xa = (\<Union>{y. \<exists>x\<in>A. y = c_set1 x} \<union> \<Union>{y. \<exists>x\<in>A. y = c_set2 x}))"
    1.12 +by blast
    1.13 +
    1.14  lemma mem_compreh_eq_iff:
    1.15 -"z \<in> {y. \<exists>x\<in>Axx. y = f x} = (\<exists> x. x \<in> Axx & z \<in> {f x})"
    1.16 +"z \<in> {y. \<exists>x\<in>A. y = f x} = (\<exists> x. x \<in> A & z \<in> {f x})"
    1.17  by blast
    1.18  
    1.19  lemma ex_mem_singleton: "(\<exists>y. y \<in> A \<and> y \<in> {x}) = (x \<in> A)"
     2.1 --- a/src/HOL/Codatatype/Tools/bnf_fp_sugar_tactics.ML	Mon Sep 17 21:13:30 2012 +0200
     2.2 +++ b/src/HOL/Codatatype/Tools/bnf_fp_sugar_tactics.ML	Mon Sep 17 21:13:30 2012 +0200
     2.3 @@ -43,18 +43,19 @@
     2.4  
     2.5  val inst_spurious_fs_tac = PRIMITIVE o inst_spurious_fs;
     2.6  
     2.7 -fun mk_set_rhs set_lhs T =
     2.8 +fun mk_set_rhs def T =
     2.9    let
    2.10 -    val Type (_, Ts0) = domain_type (fastype_of set_lhs);
    2.11 +    val lhs = snd (Logic.dest_equals (prop_of def));
    2.12 +    val Type (_, Ts0) = domain_type (fastype_of lhs);
    2.13      val Type (_, Ts) = domain_type T;
    2.14    in
    2.15 -    Term.subst_atomic_types (Ts0 ~~ Ts) set_lhs
    2.16 +    Term.subst_atomic_types (Ts0 ~~ Ts) lhs
    2.17    end;
    2.18  
    2.19 -val mk_fsts_rhs = mk_set_rhs (snd (Logic.dest_equals (prop_of @{thm fsts_def[abs_def]})));
    2.20 -val mk_snds_rhs = mk_set_rhs (snd (Logic.dest_equals (prop_of @{thm snds_def[abs_def]})));
    2.21 -val mk_setl_rhs = mk_set_rhs (snd (Logic.dest_equals (prop_of @{thm sum_setl_def[abs_def]})));
    2.22 -val mk_setr_rhs = mk_set_rhs (snd (Logic.dest_equals (prop_of @{thm sum_setr_def[abs_def]})));
    2.23 +val mk_fsts_rhs = mk_set_rhs @{thm fsts_def[abs_def]};
    2.24 +val mk_snds_rhs = mk_set_rhs @{thm snds_def[abs_def]};
    2.25 +val mk_setl_rhs = mk_set_rhs @{thm sum_setl_def[abs_def]};
    2.26 +val mk_setr_rhs = mk_set_rhs @{thm sum_setr_def[abs_def]};
    2.27  
    2.28  (* TODO: Put this in "Balanced_Tree" *)
    2.29  fun balanced_tree_middle n = n div 2;
    2.30 @@ -66,14 +67,14 @@
    2.31    let
    2.32      fun unf_prod 0 f = f
    2.33        | unf_prod 1 f = f
    2.34 -      | unf_prod m (t1 $ (t2 $ (t3 $ (t4 $ Const (_, T1) $ (t5 $ Const (_, T2) $ t6))))
    2.35 -          $ (t7 $ f $ g)) =
    2.36 +      | unf_prod m (t1 $ (t2 $ (t3 $ (t4 $ Const (@{const_name fsts}, T1) $
    2.37 +          (t5 $ Const (@{const_name snds}, T2) $ t6)))) $ (t7 $ f $ g)) =
    2.38          t1 $ (t2 $ (t3 $ (t4 $ mk_fsts_rhs T1 $ (t5 $ mk_snds_rhs T2 $ t6))))
    2.39            $ (t7 $ f $ unf_prod (m - 1) g)
    2.40        | unf_prod _ f = f;
    2.41      fun unf_sum [m] f = unf_prod m f
    2.42 -      | unf_sum ms (t1 $ (t2 $ (t3 $ (t4 $ Const (_, T1) $ (t5 $ Const (_, T2) $ t6))))
    2.43 -          $ (t7 $ f $ g)) =
    2.44 +      | unf_sum ms (t1 $ (t2 $ (t3 $ (t4 $ Const (@{const_name sum_setl}, T1) $
    2.45 +          (t5 $ Const (@{const_name sum_setr}, T2) $ t6)))) $ (t7 $ f $ g)) =
    2.46          let val (ms1, ms2) = chop (balanced_tree_middle (length ms)) ms in
    2.47            t1 $ (t2 $ (t3 $ (t4 $ mk_setl_rhs T1 $ (t5 $ mk_setr_rhs T2 $ t6))))
    2.48              $ (t7 $ unf_sum ms1 f $ unf_sum ms2 g)
    2.49 @@ -136,18 +137,11 @@
    2.50  
    2.51  val maybe_singletonI_tac = atac ORELSE' rtac @{thm singletonI};
    2.52  
    2.53 -fun mk_induct_prem_prem_endgame_tac _ 0 = maybe_singletonI_tac
    2.54 -  | mk_induct_prem_prem_endgame_tac ctxt qq =
    2.55 -    REPEAT_DETERM_N qq o
    2.56 -      (SELECT_GOAL (Local_Defs.unfold_tac ctxt
    2.57 -         @{thms trans[OF Union_iff bex_simps(6)] mem_compreh_eq_iff ex_mem_singleton}) THEN'
    2.58 -       eresolve_tac @{thms induct_set_step}) THEN' maybe_singletonI_tac;
    2.59 -
    2.60 -fun gen_UN_comprehI_tac UnI = REPEAT_DETERM o resolve_tac @{thms mem_UN_comprehI} THEN' rtac UnI;
    2.61 -
    2.62 -fun gen_UnIN_tac 1 1 = REPEAT_DETERM o resolve_tac @{thms mem_UN_comprehI'}
    2.63 -  | gen_UnIN_tac _ 1 = gen_UN_comprehI_tac @{thm UnI1} THEN' gen_UnIN_tac 1 1
    2.64 -  | gen_UnIN_tac n k = gen_UN_comprehI_tac @{thm UnI2} THEN' gen_UnIN_tac (n - 1) (k - 1);
    2.65 +fun solve_prem_prem_tac ctxt =
    2.66 +  SELECT_GOAL (Local_Defs.unfold_tac ctxt
    2.67 +    @{thms Un_iff eq_UN_compreh_Un mem_Collect_eq mem_UN_compreh_eq}) THEN'
    2.68 +  REPEAT o (etac @{thm rev_bexI} ORELSE' resolve_tac @{thms disjI1 disjI2}) THEN'
    2.69 +  (atac ORELSE' rtac refl ORELSE' rtac @{thm singletonI});
    2.70  
    2.71  val induct_prem_prem_thms =
    2.72    @{thms SUP_empty Sup_empty Sup_insert UN_compreh_bex_eq_empty UN_compreh_bex_eq_singleton
    2.73 @@ -160,7 +154,7 @@
    2.74      [select_prem_tac nn (dtac meta_spec) kk, etac meta_mp,
    2.75       SELECT_GOAL (Local_Defs.unfold_tac ctxt
    2.76         (pre_set_defs @ set_natural's @ induct_prem_prem_thms)),
    2.77 -     gen_UnIN_tac pp jj, mk_induct_prem_prem_endgame_tac ctxt qq]) (rev ppjjqqkks)) 1;
    2.78 +     solve_prem_prem_tac ctxt]) (rev ppjjqqkks)) 1;
    2.79  
    2.80  fun mk_induct_discharge_prem_tac ctxt nn n set_natural's pre_set_defs m k ppjjqqkks =
    2.81    let val r = length ppjjqqkks in