make tactic more robust in the case where "asm_simp_tac" already finishes the job
authorblanchet
Fri, 14 Sep 2012 12:09:27 +0200
changeset 503771271aca16aed
parent 50376 cc1d39529dd1
child 50378 8fc53d925629
make tactic more robust in the case where "asm_simp_tac" already finishes the job
src/HOL/Codatatype/Tools/bnf_fp_sugar.ML
src/HOL/Codatatype/Tools/bnf_fp_sugar_tactics.ML
src/HOL/Codatatype/Tools/bnf_gfp.ML
src/HOL/Codatatype/Tools/bnf_lfp.ML
     1.1 --- a/src/HOL/Codatatype/Tools/bnf_fp_sugar.ML	Fri Sep 14 12:09:27 2012 +0200
     1.2 +++ b/src/HOL/Codatatype/Tools/bnf_fp_sugar.ML	Fri Sep 14 12:09:27 2012 +0200
     1.3 @@ -52,7 +52,6 @@
     1.4  val lists_bmoc = fold (fn xs => fn t => Term.list_comb (t, xs));
     1.5  
     1.6  fun mk_id T = Const (@{const_name id}, T --> T);
     1.7 -fun mk_id_fun T = Abs (Name.uu, T, Bound 0);
     1.8  
     1.9  fun mk_tupled_fun x f xs = HOLogic.tupled_lambda x (Term.list_comb (f, xs));
    1.10  fun mk_uncurried_fun f xs = mk_tupled_fun (HOLogic.mk_tuple xs) f xs;
    1.11 @@ -66,8 +65,6 @@
    1.12      Term.lambda z (mk_sum_case (Term.lambda v v, Term.lambda c (f $ c)) $ z)
    1.13    end;
    1.14  
    1.15 -fun fold_def_rule n thm = funpow n (fn thm => thm RS fun_cong) (thm RS meta_eq_to_obj_eq) RS sym;
    1.16 -
    1.17  fun cannot_merge_types () = error "Mutually recursive types must have the same type parameters";
    1.18  
    1.19  fun merge_type_arg T T' = if T = T' then T else cannot_merge_types ();
    1.20 @@ -184,7 +181,7 @@
    1.21              let val (needs, ss') = fold_map add Ts ss in
    1.22                if exists I needs then (true, insert (op =) s ss') else (false, ss')
    1.23              end
    1.24 -          | add T ss = (member (op =) As T, ss);
    1.25 +          | add T ss = (member (op =) Bs T, ss);
    1.26        in snd oo add end;
    1.27  
    1.28      val nested_bnfs =
    1.29 @@ -204,6 +201,9 @@
    1.30      val flds = map (mk_fld As) flds0;
    1.31  
    1.32      val fpTs = map (domain_type o fastype_of) unfs;
    1.33 +
    1.34 +    val exists_fp_subtype = exists_subtype (member (op =) fpTs);
    1.35 +
    1.36      val vs = map2 (curry Free) vs' fpTs;
    1.37  
    1.38      val ctr_Tsss = map (map (map (Term.typ_subst_atomic (Bs ~~ fpTs)))) ctr_TsssBs;
    1.39 @@ -516,34 +516,76 @@
    1.40      fun derive_induct_iter_rec_thms_for_types ((ctrss, _, iters, recs, vs, xsss, ctr_defss, _, _,
    1.41          iter_defs, rec_defs), lthy) =
    1.42        let
    1.43 +        fun mk_sets_nested bnf =
    1.44 +          let
    1.45 +            val Type (T_name, Us) = T_of_bnf bnf;
    1.46 +            val lives = lives_of_bnf bnf;
    1.47 +            val sets = sets_of_bnf bnf;
    1.48 +            fun mk_set U =
    1.49 +              (case find_index (curry (op =) U) lives of
    1.50 +                ~1 => Term.dummy
    1.51 +              | i => nth sets i);
    1.52 +          in
    1.53 +            (T_name, map mk_set Us)
    1.54 +          end;
    1.55 +
    1.56 +        val setss_nested = map mk_sets_nested nested_bnfs;
    1.57 +
    1.58          val (induct_thms, induct_thm) =
    1.59            let
    1.60 -            val (ps, names_lthy) =
    1.61 +            val ((phis, phis'), names_lthy) =
    1.62                lthy
    1.63 -              |> mk_Frees "P" (map mk_predT fpTs);
    1.64 +              |> mk_Frees' "P" (map mk_predT fpTs);
    1.65  
    1.66 -            fun mk_prem_prem (x as Free (_, T)) =
    1.67 -              map HOLogic.mk_Trueprop
    1.68 +            fun mk_set Ts t =
    1.69 +              let val Type (_, Ts0) = domain_type (fastype_of t) in
    1.70 +                Term.subst_atomic_types (Ts0 ~~ Ts) t
    1.71 +              end;
    1.72 +
    1.73 +            fun mk_prem_prems names_lthy (x as Free (s, T as Type (T_name, Ts0))) =
    1.74                  (case find_index (curry (op =) T) fpTs of
    1.75 -                  ~1 => []
    1.76 -                | i => [nth ps i $ x]);
    1.77 +                  ~1 =>
    1.78 +                  (case AList.lookup (op =) setss_nested T_name of
    1.79 +                    NONE => []
    1.80 +                  | SOME raw_sets0 =>
    1.81 +                    let
    1.82 +                      val (Ts, raw_sets) =
    1.83 +                        split_list (filter (exists_fp_subtype o fst) (Ts0 ~~ raw_sets0));
    1.84 +                      val sets = map (mk_set Ts0) raw_sets;
    1.85 +                      val (ys, names_lthy') = names_lthy |> mk_Frees s Ts;
    1.86 +                      val heads =
    1.87 +                        map2 (fn y => fn set => HOLogic.mk_Trueprop (HOLogic.mk_mem (y, set $ x)))
    1.88 +                          ys sets;
    1.89 +                      val bodies = flat (map (mk_prem_prems names_lthy') ys);
    1.90 +                    in
    1.91 +                      map2 (curry Logic.mk_implies) heads bodies
    1.92 +                    end)
    1.93 +                | i => [HOLogic.mk_Trueprop (nth phis i $ x)])
    1.94 +              | mk_prem_prems _ _ = [];
    1.95  
    1.96 -            fun mk_prem p ctr ctr_Ts =
    1.97 -              let val (xs, _) = names_lthy |> mk_Frees "x" ctr_Ts in
    1.98 +            fun close_prem_prem (Free x') t =
    1.99 +              fold_rev Logic.all (map Free (drop (N + 1) (rev (Term.add_frees t (x' :: phis'))))) t;
   1.100 +
   1.101 +            fun mk_prem phi ctr ctr_Ts =
   1.102 +              let
   1.103 +                val (xs, names_lthy') = names_lthy |> mk_Frees "x" ctr_Ts;
   1.104 +                val prem_prems =
   1.105 +                  maps (fn x => map (close_prem_prem x) (mk_prem_prems names_lthy' x)) xs;
   1.106 +              in
   1.107                  fold_rev Logic.all xs
   1.108 -                  (Logic.list_implies (maps mk_prem_prem xs,
   1.109 -                     HOLogic.mk_Trueprop (p $ Term.list_comb (ctr, xs))))
   1.110 +                  (Logic.list_implies (prem_prems,
   1.111 +                     HOLogic.mk_Trueprop (phi $ Term.list_comb (ctr, xs))))
   1.112                end;
   1.113  
   1.114              val goal =
   1.115 -              fold_rev (fold_rev Logic.all) [ps, vs]
   1.116 -                (Library.foldr Logic.list_implies (map3 (map2 o mk_prem) ps ctrss ctr_Tsss,
   1.117 +              fold_rev (fold_rev Logic.all) [phis, vs]
   1.118 +                (Library.foldr Logic.list_implies (map3 (map2 o mk_prem) phis ctrss ctr_Tsss,
   1.119                     HOLogic.mk_Trueprop (Library.foldr1 HOLogic.mk_conj
   1.120 -                     (map2 (curry (op $)) ps vs))));
   1.121 +                     (map2 (curry (op $)) phis vs))));
   1.122  
   1.123              val induct_thm =
   1.124                Skip_Proof.prove lthy [] [] goal (fn {context = ctxt, ...} =>
   1.125 -                Skip_Proof.cheat_tac (Proof_Context.theory_of ctxt));
   1.126 +                mk_induct_tac ctxt);
   1.127            in
   1.128              `(conj_dests N) induct_thm
   1.129            end;
   1.130 @@ -572,7 +614,7 @@
   1.131              fun intr_calls fiter_likes maybe_cons maybe_tick maybe_mk_prodT (x as Free (_, T)) =
   1.132                if member (op =) fpTs T then
   1.133                  maybe_cons x [build_call fiter_likes (K I) (T, mk_U (K I) T) $ x]
   1.134 -              else if exists_subtype (member (op =) fpTs) T then
   1.135 +              else if exists_fp_subtype T then
   1.136                  [build_call fiter_likes maybe_tick (T, mk_U maybe_mk_prodT T) $ x]
   1.137                else
   1.138                  [x];
     2.1 --- a/src/HOL/Codatatype/Tools/bnf_fp_sugar_tactics.ML	Fri Sep 14 12:09:27 2012 +0200
     2.2 +++ b/src/HOL/Codatatype/Tools/bnf_fp_sugar_tactics.ML	Fri Sep 14 12:09:27 2012 +0200
     2.3 @@ -13,6 +13,7 @@
     2.4    val mk_fld_iff_unf_tac: Proof.context -> ctyp option list -> cterm -> cterm -> thm -> thm
     2.5      -> tactic
     2.6    val mk_half_distinct_tac: Proof.context -> thm -> thm list -> tactic
     2.7 +  val mk_induct_tac: Proof.context -> tactic
     2.8    val mk_inject_tac: Proof.context -> thm -> thm -> tactic
     2.9    val mk_iter_like_tac: thm list -> thm list -> thm list -> thm -> thm -> Proof.context -> tactic
    2.10  end;
    2.11 @@ -51,6 +52,9 @@
    2.12    Local_Defs.unfold_tac ctxt [ctr_def] THEN rtac (fld_inject RS ssubst) 1 THEN
    2.13    Local_Defs.unfold_tac ctxt @{thms sum.inject Pair_eq conj_assoc} THEN rtac refl 1;
    2.14  
    2.15 +fun mk_induct_tac ctxt =
    2.16 +  Skip_Proof.cheat_tac (Proof_Context.theory_of ctxt)(*###*);
    2.17 +
    2.18  val iter_like_thms =
    2.19    @{thms case_unit comp_def convol_def id_apply map_pair_def sum.simps(5,6) sum_map.simps
    2.20        split_conv};
    2.21 @@ -67,6 +71,6 @@
    2.22    subst_tac ctxt [fld_unf_coiter_like] 1 THEN asm_simp_tac coiter_like_ss 1 THEN
    2.23    Local_Defs.unfold_tac ctxt (pre_map_def :: coiter_like_thms @ map_ids) THEN
    2.24    Local_Defs.unfold_tac ctxt @{thms id_def} THEN
    2.25 -  (rtac refl ORELSE' subst_tac ctxt @{thms unit_eq} THEN' rtac refl) 1;
    2.26 +  TRY ((rtac refl ORELSE' subst_tac ctxt @{thms unit_eq} THEN' rtac refl) 1);
    2.27  
    2.28  end;
     3.1 --- a/src/HOL/Codatatype/Tools/bnf_gfp.ML	Fri Sep 14 12:09:27 2012 +0200
     3.2 +++ b/src/HOL/Codatatype/Tools/bnf_gfp.ML	Fri Sep 14 12:09:27 2012 +0200
     3.3 @@ -1873,7 +1873,7 @@
     3.4        ||>> mk_Frees "f" coiter_fTs
     3.5        ||>> mk_Frees "g" coiter_fTs
     3.6        ||>> mk_Frees "s" corec_sTs
     3.7 -      ||>> mk_Frees "phi" (map (fn T => T --> mk_predT T) Ts);
     3.8 +      ||>> mk_Frees "P" (map (fn T => T --> mk_predT T) Ts);
     3.9  
    3.10      fun unf_bind i = Binding.suffix_name ("_" ^ unfN) (nth bs (i - 1));
    3.11      val unf_name = Binding.name_of o unf_bind;
    3.12 @@ -2309,9 +2309,9 @@
    3.13            ||>> mk_Frees "u" uTs
    3.14            ||>> mk_Frees' "b" Ts'
    3.15            ||>> mk_Frees' "b" Ts'
    3.16 -          ||>> mk_Freess "phi" (map (fn T => map (fn U => T --> mk_predT U) Ts) passiveAs)
    3.17 +          ||>> mk_Freess "P" (map (fn T => map (fn U => T --> mk_predT U) Ts) passiveAs)
    3.18            ||>> mk_Frees "R" JRTs
    3.19 -          ||>> mk_Frees "phi" JphiTs
    3.20 +          ||>> mk_Frees "P" JphiTs
    3.21            ||>> mk_Frees "B1" B1Ts
    3.22            ||>> mk_Frees "B2" B2Ts
    3.23            ||>> mk_Frees "A" AXTs
     4.1 --- a/src/HOL/Codatatype/Tools/bnf_lfp.ML	Fri Sep 14 12:09:27 2012 +0200
     4.2 +++ b/src/HOL/Codatatype/Tools/bnf_lfp.ML	Fri Sep 14 12:09:27 2012 +0200
     4.3 @@ -794,7 +794,7 @@
     4.4        ||>> mk_Frees' "x" init_FTs
     4.5        ||>> mk_Frees "f" init_fTs
     4.6        ||>> mk_Frees "f" init_fTs
     4.7 -      ||>> mk_Frees "phi" (replicate n (mk_predT initT));
     4.8 +      ||>> mk_Frees "P" (replicate n (mk_predT initT));
     4.9  
    4.10      val II = HOLogic.mk_Collect (fst iidx', IIT, list_exists_free (II_Bs @ II_ss)
    4.11        (HOLogic.mk_conj (HOLogic.mk_eq (iidx,
    4.12 @@ -1374,7 +1374,7 @@
    4.13            ||>> mk_Frees "p2" p2Ts
    4.14            ||>> mk_Frees' "y" passiveAs
    4.15            ||>> mk_Frees "R" IRTs
    4.16 -          ||>> mk_Frees "phi" IphiTs;
    4.17 +          ||>> mk_Frees "P" IphiTs;
    4.18  
    4.19          val map_FTFT's = map2 (fn Ds =>
    4.20            mk_map_of_bnf Ds (passiveAs @ Ts) (passiveBs @ Ts')) Dss bnfs;