move size hooks together, with new one preceding old one and sharing same theory data
authorblanchet
Wed, 23 Apr 2014 10:23:27 +0200
changeset 5798541d3596d8a64
parent 57984 15cd15f9b40c
child 57986 efb39e0a89b0
move size hooks together, with new one preceding old one and sharing same theory data
src/HOL/BNF_LFP.thy
src/HOL/Fun_Def.thy
src/HOL/Lazy_Sequence.thy
src/HOL/Library/IArray.thy
src/HOL/List.thy
src/HOL/Nitpick.thy
src/HOL/Tools/BNF/bnf_lfp_size.ML
src/HOL/Tools/Function/size.ML
src/HOL/Wellfounded.thy
     1.1 --- a/src/HOL/BNF_LFP.thy	Wed Apr 23 10:23:26 2014 +0200
     1.2 +++ b/src/HOL/BNF_LFP.thy	Wed Apr 23 10:23:27 2014 +0200
     1.3 @@ -212,7 +212,35 @@
     1.4  ML_file "Tools/BNF/bnf_lfp.ML"
     1.5  ML_file "Tools/BNF/bnf_lfp_compat.ML"
     1.6  ML_file "Tools/BNF/bnf_lfp_rec_sugar_more.ML"
     1.7 +
     1.8 +
     1.9 +subsection {* Size of a datatype value *}
    1.10 +
    1.11  ML_file "Tools/BNF/bnf_lfp_size.ML"
    1.12 +ML_file "Tools/Function/size.ML"
    1.13 +setup Size.setup
    1.14 +
    1.15 +lemma size_bool[code]: "size (b\<Colon>bool) = 0"
    1.16 +  by (cases b) auto
    1.17 +
    1.18 +lemma nat_size[simp, code]: "size (n\<Colon>nat) = n"
    1.19 +  by (induct n) simp_all
    1.20 +
    1.21 +declare prod.size[no_atp]
    1.22 +
    1.23 +lemma sum_size_o_map: "sum_size g1 g2 \<circ> map_sum f1 f2 = sum_size (g1 \<circ> f1) (g2 \<circ> f2)"
    1.24 +  by (rule ext) (case_tac x, auto)
    1.25 +
    1.26 +lemma prod_size_o_map: "prod_size g1 g2 \<circ> map_prod f1 f2 = prod_size (g1 \<circ> f1) (g2 \<circ> f2)"
    1.27 +  by (rule ext) auto
    1.28 +
    1.29 +setup {*
    1.30 +BNF_LFP_Size.register_size @{type_name sum} @{const_name sum_size} @{thms sum.size}
    1.31 +  @{thms sum_size_o_map}
    1.32 +#> BNF_LFP_Size.register_size @{type_name prod} @{const_name prod_size} @{thms prod.size}
    1.33 +  @{thms prod_size_o_map}
    1.34 +*}
    1.35 +
    1.36  
    1.37  hide_fact (open) id_transfer
    1.38  
     2.1 --- a/src/HOL/Fun_Def.thy	Wed Apr 23 10:23:26 2014 +0200
     2.2 +++ b/src/HOL/Fun_Def.thy	Wed Apr 23 10:23:27 2014 +0200
     2.3 @@ -111,7 +111,8 @@
     2.4    #> Function_Fun.setup
     2.5  *}
     2.6  
     2.7 -subsection {* Measure Functions *}
     2.8 +
     2.9 +subsection {* Measure functions *}
    2.10  
    2.11  inductive is_measure :: "('a \<Rightarrow> nat) \<Rightarrow> bool"
    2.12  where is_measure_trivial: "is_measure f"
    2.13 @@ -137,7 +138,7 @@
    2.14  setup Lexicographic_Order.setup
    2.15  
    2.16  
    2.17 -subsection {* Congruence Rules *}
    2.18 +subsection {* Congruence rules *}
    2.19  
    2.20  lemma let_cong [fundef_cong]:
    2.21    "M = N \<Longrightarrow> (\<And>x. x = N \<Longrightarrow> f x = g x) \<Longrightarrow> Let M f = Let N g"
    2.22 @@ -156,22 +157,22 @@
    2.23    "f (g x) = f' (g' x') \<Longrightarrow> (f o g) x = (f' o g') x'"
    2.24    unfolding o_apply .
    2.25  
    2.26 +
    2.27  subsection {* Simp rules for termination proofs *}
    2.28  
    2.29 -lemma termination_basic_simps[termination_simp]:
    2.30 -  "x < (y::nat) \<Longrightarrow> x < y + z"
    2.31 -  "x < z \<Longrightarrow> x < y + z"
    2.32 -  "x \<le> y \<Longrightarrow> x \<le> y + (z::nat)"
    2.33 -  "x \<le> z \<Longrightarrow> x \<le> y + (z::nat)"
    2.34 -  "x < y \<Longrightarrow> x \<le> (y::nat)"
    2.35 -by arith+
    2.36 -
    2.37 -declare le_imp_less_Suc[termination_simp]
    2.38 +declare
    2.39 +  trans_less_add1[termination_simp]
    2.40 +  trans_less_add2[termination_simp]
    2.41 +  trans_le_add1[termination_simp]
    2.42 +  trans_le_add2[termination_simp]
    2.43 +  less_imp_le_nat[termination_simp]
    2.44 +  le_imp_less_Suc[termination_simp]
    2.45  
    2.46  lemma prod_size_simp[termination_simp]:
    2.47    "prod_size f g p = f (fst p) + g (snd p) + Suc 0"
    2.48  by (induct p) auto
    2.49  
    2.50 +
    2.51  subsection {* Decomposition *}
    2.52  
    2.53  lemma less_by_empty:
    2.54 @@ -185,7 +186,7 @@
    2.55  by (auto simp add: wf_comp_self[of R])
    2.56  
    2.57  
    2.58 -subsection {* Reduction Pairs *}
    2.59 +subsection {* Reduction pairs *}
    2.60  
    2.61  definition
    2.62    "reduction_pair P = (wf (fst P) \<and> fst P O snd P \<subseteq> fst P)"
     3.1 --- a/src/HOL/Lazy_Sequence.thy	Wed Apr 23 10:23:26 2014 +0200
     3.2 +++ b/src/HOL/Lazy_Sequence.thy	Wed Apr 23 10:23:27 2014 +0200
     3.3 @@ -28,7 +28,7 @@
     3.4    by (auto intro: lazy_sequence_eqI)
     3.5  
     3.6  lemma lazy_sequence_size_eq:
     3.7 -  "lazy_sequence_size f xq = Suc (list_size f (list_of_lazy_sequence xq))"
     3.8 +  "lazy_sequence_size f xq = Suc (size_list f (list_of_lazy_sequence xq))"
     3.9    by (cases xq) simp
    3.10  
    3.11  lemma size_lazy_sequence_eq [code]:
     4.1 --- a/src/HOL/Library/IArray.thy	Wed Apr 23 10:23:26 2014 +0200
     4.2 +++ b/src/HOL/Library/IArray.thy	Wed Apr 23 10:23:27 2014 +0200
     4.3 @@ -59,7 +59,7 @@
     4.4  by (cases as) simp
     4.5  
     4.6  lemma [code]:
     4.7 -"iarray_size f as = Suc (list_size f (IArray.list_of as))"
     4.8 +"iarray_size f as = Suc (size_list f (IArray.list_of as))"
     4.9  by (cases as) simp
    4.10  
    4.11  lemma [code]:
     5.1 --- a/src/HOL/List.thy	Wed Apr 23 10:23:26 2014 +0200
     5.2 +++ b/src/HOL/List.thy	Wed Apr 23 10:23:27 2014 +0200
     5.3 @@ -3488,8 +3488,8 @@
     5.4    "x \<in> set xs \<Longrightarrow> listsum (map f xs) = f x + listsum (map f (remove1 x xs))"
     5.5    by (induct xs) (auto simp add: ac_simps)
     5.6  
     5.7 -lemma (in monoid_add) list_size_conv_listsum:
     5.8 -  "list_size f xs = listsum (map f xs) + size xs"
     5.9 +lemma (in monoid_add) size_list_conv_listsum:
    5.10 +  "size_list f xs = listsum (map f xs) + size xs"
    5.11    by (induct xs) auto
    5.12  
    5.13  lemma (in monoid_add) length_concat:
    5.14 @@ -5945,28 +5945,28 @@
    5.15  
    5.16  subsection {* Size function *}
    5.17  
    5.18 -lemma [measure_function]: "is_measure f \<Longrightarrow> is_measure (list_size f)"
    5.19 +lemma [measure_function]: "is_measure f \<Longrightarrow> is_measure (size_list f)"
    5.20  by (rule is_measure_trivial)
    5.21  
    5.22 -lemma [measure_function]: "is_measure f \<Longrightarrow> is_measure (option_size f)"
    5.23 +lemma [measure_function]: "is_measure f \<Longrightarrow> is_measure (size_option f)"
    5.24  by (rule is_measure_trivial)
    5.25  
    5.26 -lemma list_size_estimation[termination_simp]: 
    5.27 -  "x \<in> set xs \<Longrightarrow> y < f x \<Longrightarrow> y < list_size f xs"
    5.28 +lemma size_list_estimation[termination_simp]: 
    5.29 +  "x \<in> set xs \<Longrightarrow> y < f x \<Longrightarrow> y < size_list f xs"
    5.30  by (induct xs) auto
    5.31  
    5.32 -lemma list_size_estimation'[termination_simp]: 
    5.33 -  "x \<in> set xs \<Longrightarrow> y \<le> f x \<Longrightarrow> y \<le> list_size f xs"
    5.34 +lemma size_list_estimation'[termination_simp]: 
    5.35 +  "x \<in> set xs \<Longrightarrow> y \<le> f x \<Longrightarrow> y \<le> size_list f xs"
    5.36  by (induct xs) auto
    5.37  
    5.38 -lemma list_size_map[simp]: "list_size f (map g xs) = list_size (f o g) xs"
    5.39 +lemma size_list_map[simp]: "size_list f (map g xs) = size_list (f o g) xs"
    5.40  by (induct xs) auto
    5.41  
    5.42 -lemma list_size_append[simp]: "list_size f (xs @ ys) = list_size f xs + list_size f ys"
    5.43 +lemma size_list_append[simp]: "size_list f (xs @ ys) = size_list f xs + size_list f ys"
    5.44  by (induct xs, auto)
    5.45  
    5.46 -lemma list_size_pointwise[termination_simp]: 
    5.47 -  "(\<And>x. x \<in> set xs \<Longrightarrow> f x \<le> g x) \<Longrightarrow> list_size f xs \<le> list_size g xs"
    5.48 +lemma size_list_pointwise[termination_simp]: 
    5.49 +  "(\<And>x. x \<in> set xs \<Longrightarrow> f x \<le> g x) \<Longrightarrow> size_list f xs \<le> size_list g xs"
    5.50  by (induct xs) force+
    5.51  
    5.52  
    5.53 @@ -6757,7 +6757,7 @@
    5.54  
    5.55  lemma length_transfer [transfer_rule]:
    5.56    "(list_all2 A ===> op =) length length"
    5.57 -  unfolding list_size_overloaded_def by transfer_prover
    5.58 +  unfolding size_list_overloaded_def size_list_def by transfer_prover
    5.59  
    5.60  lemma rotate1_transfer [transfer_rule]:
    5.61    "(list_all2 A ===> list_all2 A) rotate1 rotate1"
     6.1 --- a/src/HOL/Nitpick.thy	Wed Apr 23 10:23:26 2014 +0200
     6.2 +++ b/src/HOL/Nitpick.thy	Wed Apr 23 10:23:27 2014 +0200
     6.3 @@ -113,9 +113,8 @@
     6.4  
     6.5  declare nat.case [nitpick_simp del]
     6.6  
     6.7 -lemma list_size_simp [nitpick_simp]:
     6.8 -"list_size f xs = (if xs = [] then 0
     6.9 -                   else Suc (f (hd xs) + list_size f (tl xs)))"
    6.10 +lemma size_list_simp [nitpick_simp]:
    6.11 +"size_list f xs = (if xs = [] then 0 else Suc (f (hd xs) + size_list f (tl xs)))"
    6.12  "size xs = (if xs = [] then 0 else Suc (size (tl xs)))"
    6.13  by (cases xs) auto
    6.14  
    6.15 @@ -145,8 +144,9 @@
    6.16  definition Frac :: "int \<times> int \<Rightarrow> bool" where
    6.17  "Frac \<equiv> \<lambda>(a, b). b > 0 \<and> int_gcd a b = 1"
    6.18  
    6.19 -axiomatization Abs_Frac :: "int \<times> int \<Rightarrow> 'a"
    6.20 -           and Rep_Frac :: "'a \<Rightarrow> int \<times> int"
    6.21 +axiomatization
    6.22 +  Abs_Frac :: "int \<times> int \<Rightarrow> 'a" and
    6.23 +  Rep_Frac :: "'a \<Rightarrow> int \<times> int"
    6.24  
    6.25  definition zero_frac :: 'a where
    6.26  "zero_frac \<equiv> Abs_Frac (0, 1)"
    6.27 @@ -244,7 +244,7 @@
    6.28  hide_fact (open) Ex1_unfold rtrancl_unfold rtranclp_unfold tranclp_unfold
    6.29      prod_def refl'_def wf'_def card'_def setsum'_def
    6.30      fold_graph'_def The_psimp Eps_psimp case_unit_unfold case_nat_unfold
    6.31 -    list_size_simp nat_gcd_def nat_lcm_def int_gcd_def int_lcm_def Frac_def
    6.32 +    size_list_simp nat_gcd_def nat_lcm_def int_gcd_def int_lcm_def Frac_def
    6.33      zero_frac_def one_frac_def num_def denom_def norm_frac_def frac_def
    6.34      plus_frac_def times_frac_def uminus_frac_def number_of_frac_def
    6.35      inverse_frac_def less_frac_def less_eq_frac_def of_frac_def wf_wfrec'_def
     7.1 --- a/src/HOL/Tools/BNF/bnf_lfp_size.ML	Wed Apr 23 10:23:26 2014 +0200
     7.2 +++ b/src/HOL/Tools/BNF/bnf_lfp_size.ML	Wed Apr 23 10:23:27 2014 +0200
     7.3 @@ -8,6 +8,7 @@
     7.4  signature BNF_LFP_SIZE =
     7.5  sig
     7.6    val register_size: string -> string -> thm list -> thm list -> theory -> theory
     7.7 +  val lookup_size: theory -> string -> (string * (thm list * thm list)) option
     7.8  end;
     7.9  
    7.10  structure BNF_LFP_Size : BNF_LFP_SIZE =
    7.11 @@ -33,7 +34,9 @@
    7.12  );
    7.13  
    7.14  fun register_size T_name size_name size_simps size_o_maps =
    7.15 -  Data.map (Symtab.update_new (T_name, (size_name, (size_simps, size_o_maps))));
    7.16 +  Data.map (Symtab.update (T_name, (size_name, (size_simps, size_o_maps))));
    7.17 +
    7.18 +val lookup_size = Symtab.lookup o Data.get;
    7.19  
    7.20  val zero_nat = @{const zero_class.zero (nat)};
    7.21  
    7.22 @@ -224,8 +227,13 @@
    7.23  
    7.24        val maps0 = map map_of_bnf fp_bnfs;
    7.25  
    7.26 +      (* This disables much of the functionality of the size extension within a locale. It is not
    7.27 +         clear how to make the code below work with locales, given that interpretations are based on
    7.28 +         theories. *)
    7.29 +      val has_hyps = not (null (Thm.hyps_of (hd (hd rec_thmss))));
    7.30 +
    7.31        val (rec_o_map_thmss, size_o_map_thmss) =
    7.32 -        if live = 0 then
    7.33 +        if has_hyps orelse live = 0 then
    7.34            `I (replicate nn [])
    7.35          else
    7.36            let
    7.37 @@ -306,16 +314,19 @@
    7.38  
    7.39        val (_, thy4) = thy3
    7.40          |> fold_map4 (fn T_name => fn size_simps => fn rec_o_map_thms => fn size_o_map_thms =>
    7.41 -            let val qualify = Binding.qualify true (Long_Name.base_name T_name) in
    7.42 -              Global_Theory.note_thmss ""
    7.43 -                ([((qualify (Binding.name rec_o_mapN), []), [(rec_o_map_thms, [])]),
    7.44 -                  ((qualify (Binding.name sizeN),
    7.45 -                     [Simplifier.simp_add, Nitpick_Simps.add, Thm.declaration_attribute
    7.46 -                        (fn thm => Context.mapping (Code.add_default_eqn thm) I)]),
    7.47 -                   [(size_simps, [])]),
    7.48 -                  ((qualify (Binding.name size_o_mapN), []), [(size_o_map_thms, [])])]
    7.49 -                 |> filter_out (forall (null o fst) o snd))
    7.50 -            end)
    7.51 +            if has_hyps then
    7.52 +              pair []
    7.53 +            else
    7.54 +              let val qualify = Binding.qualify true (Long_Name.base_name T_name) in
    7.55 +                Global_Theory.note_thmss ""
    7.56 +                  ([((qualify (Binding.name rec_o_mapN), []), [(rec_o_map_thms, [])]),
    7.57 +                    ((qualify (Binding.name sizeN),
    7.58 +                       [Simplifier.simp_add, Nitpick_Simps.add, Thm.declaration_attribute
    7.59 +                          (fn thm => Context.mapping (Code.add_default_eqn thm) I)]),
    7.60 +                     [(size_simps, [])]),
    7.61 +                    ((qualify (Binding.name size_o_mapN), []), [(size_o_map_thms, [])])]
    7.62 +                   |> filter_out (forall (null o fst) o snd))
    7.63 +              end)
    7.64            T_names (map2 append size_simpss overloaded_size_simpss) rec_o_map_thmss size_o_map_thmss
    7.65          ||> Spec_Rules.add_global Spec_Rules.Equational (size_consts, size_simps);
    7.66      in
     8.1 --- a/src/HOL/Tools/Function/size.ML	Wed Apr 23 10:23:26 2014 +0200
     8.2 +++ b/src/HOL/Tools/Function/size.ML	Wed Apr 23 10:23:27 2014 +0200
     8.3 @@ -6,23 +6,12 @@
     8.4  
     8.5  signature SIZE =
     8.6  sig
     8.7 -  val size_thms: theory -> string -> thm list
     8.8    val setup: theory -> theory
     8.9  end;
    8.10  
    8.11  structure Size: SIZE =
    8.12  struct
    8.13  
    8.14 -structure Data = Theory_Data
    8.15 -(
    8.16 -  type T = (string * thm list) Symtab.table;
    8.17 -  val empty = Symtab.empty;
    8.18 -  val extend = I
    8.19 -  fun merge data = Symtab.merge (K true) data;
    8.20 -);
    8.21 -
    8.22 -val lookup_size = Data.get #> Symtab.lookup;
    8.23 -
    8.24  fun plus (t1, t2) = Const (@{const_name Groups.plus},
    8.25    HOLogic.natT --> HOLogic.natT --> HOLogic.natT) $ t1 $ t2;
    8.26  
    8.27 @@ -35,15 +24,13 @@
    8.28                 map (fn U => U --> HOLogic.natT) Ts @ [T] ---> HOLogic.natT),
    8.29                   map (size_of_type' f g h) Ts))
    8.30           | NONE => NONE))
    8.31 -  | size_of_type f g h (TFree (s, _)) = h s
    8.32 +  | size_of_type _ _ h (TFree (s, _)) = h s
    8.33  and size_of_type' f g h T = (case size_of_type f g h T of
    8.34        NONE => Abs ("x", T, HOLogic.zero)
    8.35      | SOME t => t);
    8.36  
    8.37  fun is_poly thy (Datatype_Aux.DtType (name, dts)) =
    8.38 -      (case lookup_size thy name of
    8.39 -         NONE => false
    8.40 -       | SOME _ => exists (is_poly thy) dts)
    8.41 +      is_some (BNF_LFP_Size.lookup_size thy name) andalso exists (is_poly thy) dts
    8.42    | is_poly _ _ = true;
    8.43  
    8.44  fun constrs_of thy name =
    8.45 @@ -66,7 +53,6 @@
    8.46        thy
    8.47      else
    8.48        let
    8.49 -        val (rec_names1, rec_names2) = chop l rec_names;
    8.50          val recTs = Datatype_Aux.get_rec_types descr;
    8.51          val (recTs1, recTs2) = chop l recTs;
    8.52          val (_, (_, paramdts, _)) :: _ = descr;
    8.53 @@ -82,8 +68,8 @@
    8.54          val param_size = AList.lookup op = param_size_fs;
    8.55  
    8.56          val extra_rewrites = descr |> map (#1 o snd) |> distinct op = |>
    8.57 -          map_filter (Option.map snd o lookup_size thy) |> flat;
    8.58 -        val extra_size = Option.map fst o lookup_size thy;
    8.59 +          map_filter (Option.map (fst o snd) o BNF_LFP_Size.lookup_size thy) |> flat;
    8.60 +        val extra_size = Option.map fst o BNF_LFP_Size.lookup_size thy;
    8.61  
    8.62          val (((size_names, size_fns), def_names), def_names') =
    8.63            recTs1 |> map (fn T as Type (s, _) =>
    8.64 @@ -160,7 +146,7 @@
    8.65              size_def_thms @ size_def_thms' @ rec_rewrites @ extra_rewrites;
    8.66          val xs = map (fn i => "x" ^ string_of_int i) (1 upto length recTs2);
    8.67  
    8.68 -        fun mk_unfolded_size_eq tab size_ofp fs (p as (x, T), r) =
    8.69 +        fun mk_unfolded_size_eq tab size_ofp fs (p as (_, T), r) =
    8.70            HOLogic.mk_eq (app fs r $ Free p,
    8.71              the (size_of_type tab extra_size size_ofp T) $ Free p);
    8.72  
    8.73 @@ -181,7 +167,7 @@
    8.74            let
    8.75              val Ts = map (Datatype_Aux.typ_of_dtyp descr) cargs;
    8.76              val tnames = Name.variant_list f_names (Datatype_Prop.make_tnames Ts);
    8.77 -            val ts = map_filter (fn (sT as (s, T), dt) =>
    8.78 +            val ts = map_filter (fn (sT as (_, T), dt) =>
    8.79                Option.map (fn sz => sz $ Free sT)
    8.80                  (if p dt then size_of_type size_of extra_size size_ofp T
    8.81                   else NONE)) (tnames ~~ Ts ~~ cargs)
    8.82 @@ -220,12 +206,13 @@
    8.83                [(size_eqns, [])])];
    8.84  
    8.85        in
    8.86 -        Data.map (fold (Symtab.update_new o apsnd (rpair size_thms))
    8.87 -          (new_type_names ~~ size_names)) thy''
    8.88 +        fold2 (fn new_type_name => fn size_name =>
    8.89 +            BNF_LFP_Size.register_size new_type_name size_name [] size_thms)
    8.90 +          new_type_names size_names thy''
    8.91        end
    8.92    end;
    8.93  
    8.94 -fun add_size_thms config (new_type_names as name :: _) thy =
    8.95 +fun add_size_thms _ (new_type_names as name :: _) thy =
    8.96    let
    8.97      val info as {descr, ...} = Datatype_Data.the_info thy name;
    8.98      val prefix = space_implode "_" (map Long_Name.base_name new_type_names);
    8.99 @@ -241,8 +228,6 @@
   8.100        |> Sign.restore_naming thy
   8.101    end;
   8.102  
   8.103 -val size_thms = snd oo (the oo lookup_size);
   8.104 -
   8.105  val setup = Datatype_Data.interpretation add_size_thms;
   8.106  
   8.107  end;
     9.1 --- a/src/HOL/Wellfounded.thy	Wed Apr 23 10:23:26 2014 +0200
     9.2 +++ b/src/HOL/Wellfounded.thy	Wed Apr 23 10:23:27 2014 +0200
     9.3 @@ -848,20 +848,6 @@
     9.4  done
     9.5  
     9.6  
     9.7 -subsection {* size of a datatype value *}
     9.8 -
     9.9 -ML_file "Tools/Function/size.ML"
    9.10 -setup Size.setup
    9.11 -
    9.12 -lemma size_bool [code]:
    9.13 -  "size (b\<Colon>bool) = 0" by (cases b) auto
    9.14 -
    9.15 -lemma nat_size [simp, code]: "size (n\<Colon>nat) = n"
    9.16 -  by (induct n) simp_all
    9.17 -
    9.18 -declare prod.size [no_atp]
    9.19 -
    9.20 -
    9.21  hide_const (open) acc accp
    9.22  
    9.23  end