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 56643 41d3596d8a64
parent 56642 15cd15f9b40c
child 56644 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
--- a/src/HOL/BNF_LFP.thy	Wed Apr 23 10:23:26 2014 +0200
+++ b/src/HOL/BNF_LFP.thy	Wed Apr 23 10:23:27 2014 +0200
@@ -212,7 +212,35 @@
 ML_file "Tools/BNF/bnf_lfp.ML"
 ML_file "Tools/BNF/bnf_lfp_compat.ML"
 ML_file "Tools/BNF/bnf_lfp_rec_sugar_more.ML"
+
+
+subsection {* Size of a datatype value *}
+
 ML_file "Tools/BNF/bnf_lfp_size.ML"
+ML_file "Tools/Function/size.ML"
+setup Size.setup
+
+lemma size_bool[code]: "size (b\<Colon>bool) = 0"
+  by (cases b) auto
+
+lemma nat_size[simp, code]: "size (n\<Colon>nat) = n"
+  by (induct n) simp_all
+
+declare prod.size[no_atp]
+
+lemma sum_size_o_map: "sum_size g1 g2 \<circ> map_sum f1 f2 = sum_size (g1 \<circ> f1) (g2 \<circ> f2)"
+  by (rule ext) (case_tac x, auto)
+
+lemma prod_size_o_map: "prod_size g1 g2 \<circ> map_prod f1 f2 = prod_size (g1 \<circ> f1) (g2 \<circ> f2)"
+  by (rule ext) auto
+
+setup {*
+BNF_LFP_Size.register_size @{type_name sum} @{const_name sum_size} @{thms sum.size}
+  @{thms sum_size_o_map}
+#> BNF_LFP_Size.register_size @{type_name prod} @{const_name prod_size} @{thms prod.size}
+  @{thms prod_size_o_map}
+*}
+
 
 hide_fact (open) id_transfer
 
--- a/src/HOL/Fun_Def.thy	Wed Apr 23 10:23:26 2014 +0200
+++ b/src/HOL/Fun_Def.thy	Wed Apr 23 10:23:27 2014 +0200
@@ -111,7 +111,8 @@
   #> Function_Fun.setup
 *}
 
-subsection {* Measure Functions *}
+
+subsection {* Measure functions *}
 
 inductive is_measure :: "('a \<Rightarrow> nat) \<Rightarrow> bool"
 where is_measure_trivial: "is_measure f"
@@ -137,7 +138,7 @@
 setup Lexicographic_Order.setup
 
 
-subsection {* Congruence Rules *}
+subsection {* Congruence rules *}
 
 lemma let_cong [fundef_cong]:
   "M = N \<Longrightarrow> (\<And>x. x = N \<Longrightarrow> f x = g x) \<Longrightarrow> Let M f = Let N g"
@@ -156,22 +157,22 @@
   "f (g x) = f' (g' x') \<Longrightarrow> (f o g) x = (f' o g') x'"
   unfolding o_apply .
 
+
 subsection {* Simp rules for termination proofs *}
 
-lemma termination_basic_simps[termination_simp]:
-  "x < (y::nat) \<Longrightarrow> x < y + z"
-  "x < z \<Longrightarrow> x < y + z"
-  "x \<le> y \<Longrightarrow> x \<le> y + (z::nat)"
-  "x \<le> z \<Longrightarrow> x \<le> y + (z::nat)"
-  "x < y \<Longrightarrow> x \<le> (y::nat)"
-by arith+
-
-declare le_imp_less_Suc[termination_simp]
+declare
+  trans_less_add1[termination_simp]
+  trans_less_add2[termination_simp]
+  trans_le_add1[termination_simp]
+  trans_le_add2[termination_simp]
+  less_imp_le_nat[termination_simp]
+  le_imp_less_Suc[termination_simp]
 
 lemma prod_size_simp[termination_simp]:
   "prod_size f g p = f (fst p) + g (snd p) + Suc 0"
 by (induct p) auto
 
+
 subsection {* Decomposition *}
 
 lemma less_by_empty:
@@ -185,7 +186,7 @@
 by (auto simp add: wf_comp_self[of R])
 
 
-subsection {* Reduction Pairs *}
+subsection {* Reduction pairs *}
 
 definition
   "reduction_pair P = (wf (fst P) \<and> fst P O snd P \<subseteq> fst P)"
--- a/src/HOL/Lazy_Sequence.thy	Wed Apr 23 10:23:26 2014 +0200
+++ b/src/HOL/Lazy_Sequence.thy	Wed Apr 23 10:23:27 2014 +0200
@@ -28,7 +28,7 @@
   by (auto intro: lazy_sequence_eqI)
 
 lemma lazy_sequence_size_eq:
-  "lazy_sequence_size f xq = Suc (list_size f (list_of_lazy_sequence xq))"
+  "lazy_sequence_size f xq = Suc (size_list f (list_of_lazy_sequence xq))"
   by (cases xq) simp
 
 lemma size_lazy_sequence_eq [code]:
--- a/src/HOL/Library/IArray.thy	Wed Apr 23 10:23:26 2014 +0200
+++ b/src/HOL/Library/IArray.thy	Wed Apr 23 10:23:27 2014 +0200
@@ -59,7 +59,7 @@
 by (cases as) simp
 
 lemma [code]:
-"iarray_size f as = Suc (list_size f (IArray.list_of as))"
+"iarray_size f as = Suc (size_list f (IArray.list_of as))"
 by (cases as) simp
 
 lemma [code]:
--- a/src/HOL/List.thy	Wed Apr 23 10:23:26 2014 +0200
+++ b/src/HOL/List.thy	Wed Apr 23 10:23:27 2014 +0200
@@ -3488,8 +3488,8 @@
   "x \<in> set xs \<Longrightarrow> listsum (map f xs) = f x + listsum (map f (remove1 x xs))"
   by (induct xs) (auto simp add: ac_simps)
 
-lemma (in monoid_add) list_size_conv_listsum:
-  "list_size f xs = listsum (map f xs) + size xs"
+lemma (in monoid_add) size_list_conv_listsum:
+  "size_list f xs = listsum (map f xs) + size xs"
   by (induct xs) auto
 
 lemma (in monoid_add) length_concat:
@@ -5945,28 +5945,28 @@
 
 subsection {* Size function *}
 
-lemma [measure_function]: "is_measure f \<Longrightarrow> is_measure (list_size f)"
+lemma [measure_function]: "is_measure f \<Longrightarrow> is_measure (size_list f)"
 by (rule is_measure_trivial)
 
-lemma [measure_function]: "is_measure f \<Longrightarrow> is_measure (option_size f)"
+lemma [measure_function]: "is_measure f \<Longrightarrow> is_measure (size_option f)"
 by (rule is_measure_trivial)
 
-lemma list_size_estimation[termination_simp]: 
-  "x \<in> set xs \<Longrightarrow> y < f x \<Longrightarrow> y < list_size f xs"
+lemma size_list_estimation[termination_simp]: 
+  "x \<in> set xs \<Longrightarrow> y < f x \<Longrightarrow> y < size_list f xs"
 by (induct xs) auto
 
-lemma list_size_estimation'[termination_simp]: 
-  "x \<in> set xs \<Longrightarrow> y \<le> f x \<Longrightarrow> y \<le> list_size f xs"
+lemma size_list_estimation'[termination_simp]: 
+  "x \<in> set xs \<Longrightarrow> y \<le> f x \<Longrightarrow> y \<le> size_list f xs"
 by (induct xs) auto
 
-lemma list_size_map[simp]: "list_size f (map g xs) = list_size (f o g) xs"
+lemma size_list_map[simp]: "size_list f (map g xs) = size_list (f o g) xs"
 by (induct xs) auto
 
-lemma list_size_append[simp]: "list_size f (xs @ ys) = list_size f xs + list_size f ys"
+lemma size_list_append[simp]: "size_list f (xs @ ys) = size_list f xs + size_list f ys"
 by (induct xs, auto)
 
-lemma list_size_pointwise[termination_simp]: 
-  "(\<And>x. x \<in> set xs \<Longrightarrow> f x \<le> g x) \<Longrightarrow> list_size f xs \<le> list_size g xs"
+lemma size_list_pointwise[termination_simp]: 
+  "(\<And>x. x \<in> set xs \<Longrightarrow> f x \<le> g x) \<Longrightarrow> size_list f xs \<le> size_list g xs"
 by (induct xs) force+
 
 
@@ -6757,7 +6757,7 @@
 
 lemma length_transfer [transfer_rule]:
   "(list_all2 A ===> op =) length length"
-  unfolding list_size_overloaded_def by transfer_prover
+  unfolding size_list_overloaded_def size_list_def by transfer_prover
 
 lemma rotate1_transfer [transfer_rule]:
   "(list_all2 A ===> list_all2 A) rotate1 rotate1"
--- a/src/HOL/Nitpick.thy	Wed Apr 23 10:23:26 2014 +0200
+++ b/src/HOL/Nitpick.thy	Wed Apr 23 10:23:27 2014 +0200
@@ -113,9 +113,8 @@
 
 declare nat.case [nitpick_simp del]
 
-lemma list_size_simp [nitpick_simp]:
-"list_size f xs = (if xs = [] then 0
-                   else Suc (f (hd xs) + list_size f (tl xs)))"
+lemma size_list_simp [nitpick_simp]:
+"size_list f xs = (if xs = [] then 0 else Suc (f (hd xs) + size_list f (tl xs)))"
 "size xs = (if xs = [] then 0 else Suc (size (tl xs)))"
 by (cases xs) auto
 
@@ -145,8 +144,9 @@
 definition Frac :: "int \<times> int \<Rightarrow> bool" where
 "Frac \<equiv> \<lambda>(a, b). b > 0 \<and> int_gcd a b = 1"
 
-axiomatization Abs_Frac :: "int \<times> int \<Rightarrow> 'a"
-           and Rep_Frac :: "'a \<Rightarrow> int \<times> int"
+axiomatization
+  Abs_Frac :: "int \<times> int \<Rightarrow> 'a" and
+  Rep_Frac :: "'a \<Rightarrow> int \<times> int"
 
 definition zero_frac :: 'a where
 "zero_frac \<equiv> Abs_Frac (0, 1)"
@@ -244,7 +244,7 @@
 hide_fact (open) Ex1_unfold rtrancl_unfold rtranclp_unfold tranclp_unfold
     prod_def refl'_def wf'_def card'_def setsum'_def
     fold_graph'_def The_psimp Eps_psimp case_unit_unfold case_nat_unfold
-    list_size_simp nat_gcd_def nat_lcm_def int_gcd_def int_lcm_def Frac_def
+    size_list_simp nat_gcd_def nat_lcm_def int_gcd_def int_lcm_def Frac_def
     zero_frac_def one_frac_def num_def denom_def norm_frac_def frac_def
     plus_frac_def times_frac_def uminus_frac_def number_of_frac_def
     inverse_frac_def less_frac_def less_eq_frac_def of_frac_def wf_wfrec'_def
--- a/src/HOL/Tools/BNF/bnf_lfp_size.ML	Wed Apr 23 10:23:26 2014 +0200
+++ b/src/HOL/Tools/BNF/bnf_lfp_size.ML	Wed Apr 23 10:23:27 2014 +0200
@@ -8,6 +8,7 @@
 signature BNF_LFP_SIZE =
 sig
   val register_size: string -> string -> thm list -> thm list -> theory -> theory
+  val lookup_size: theory -> string -> (string * (thm list * thm list)) option
 end;
 
 structure BNF_LFP_Size : BNF_LFP_SIZE =
@@ -33,7 +34,9 @@
 );
 
 fun register_size T_name size_name size_simps size_o_maps =
-  Data.map (Symtab.update_new (T_name, (size_name, (size_simps, size_o_maps))));
+  Data.map (Symtab.update (T_name, (size_name, (size_simps, size_o_maps))));
+
+val lookup_size = Symtab.lookup o Data.get;
 
 val zero_nat = @{const zero_class.zero (nat)};
 
@@ -224,8 +227,13 @@
 
       val maps0 = map map_of_bnf fp_bnfs;
 
+      (* This disables much of the functionality of the size extension within a locale. It is not
+         clear how to make the code below work with locales, given that interpretations are based on
+         theories. *)
+      val has_hyps = not (null (Thm.hyps_of (hd (hd rec_thmss))));
+
       val (rec_o_map_thmss, size_o_map_thmss) =
-        if live = 0 then
+        if has_hyps orelse live = 0 then
           `I (replicate nn [])
         else
           let
@@ -306,16 +314,19 @@
 
       val (_, thy4) = thy3
         |> fold_map4 (fn T_name => fn size_simps => fn rec_o_map_thms => fn size_o_map_thms =>
-            let val qualify = Binding.qualify true (Long_Name.base_name T_name) in
-              Global_Theory.note_thmss ""
-                ([((qualify (Binding.name rec_o_mapN), []), [(rec_o_map_thms, [])]),
-                  ((qualify (Binding.name sizeN),
-                     [Simplifier.simp_add, Nitpick_Simps.add, Thm.declaration_attribute
-                        (fn thm => Context.mapping (Code.add_default_eqn thm) I)]),
-                   [(size_simps, [])]),
-                  ((qualify (Binding.name size_o_mapN), []), [(size_o_map_thms, [])])]
-                 |> filter_out (forall (null o fst) o snd))
-            end)
+            if has_hyps then
+              pair []
+            else
+              let val qualify = Binding.qualify true (Long_Name.base_name T_name) in
+                Global_Theory.note_thmss ""
+                  ([((qualify (Binding.name rec_o_mapN), []), [(rec_o_map_thms, [])]),
+                    ((qualify (Binding.name sizeN),
+                       [Simplifier.simp_add, Nitpick_Simps.add, Thm.declaration_attribute
+                          (fn thm => Context.mapping (Code.add_default_eqn thm) I)]),
+                     [(size_simps, [])]),
+                    ((qualify (Binding.name size_o_mapN), []), [(size_o_map_thms, [])])]
+                   |> filter_out (forall (null o fst) o snd))
+              end)
           T_names (map2 append size_simpss overloaded_size_simpss) rec_o_map_thmss size_o_map_thmss
         ||> Spec_Rules.add_global Spec_Rules.Equational (size_consts, size_simps);
     in
--- a/src/HOL/Tools/Function/size.ML	Wed Apr 23 10:23:26 2014 +0200
+++ b/src/HOL/Tools/Function/size.ML	Wed Apr 23 10:23:27 2014 +0200
@@ -6,23 +6,12 @@
 
 signature SIZE =
 sig
-  val size_thms: theory -> string -> thm list
   val setup: theory -> theory
 end;
 
 structure Size: SIZE =
 struct
 
-structure Data = Theory_Data
-(
-  type T = (string * thm list) Symtab.table;
-  val empty = Symtab.empty;
-  val extend = I
-  fun merge data = Symtab.merge (K true) data;
-);
-
-val lookup_size = Data.get #> Symtab.lookup;
-
 fun plus (t1, t2) = Const (@{const_name Groups.plus},
   HOLogic.natT --> HOLogic.natT --> HOLogic.natT) $ t1 $ t2;
 
@@ -35,15 +24,13 @@
                map (fn U => U --> HOLogic.natT) Ts @ [T] ---> HOLogic.natT),
                  map (size_of_type' f g h) Ts))
          | NONE => NONE))
-  | size_of_type f g h (TFree (s, _)) = h s
+  | size_of_type _ _ h (TFree (s, _)) = h s
 and size_of_type' f g h T = (case size_of_type f g h T of
       NONE => Abs ("x", T, HOLogic.zero)
     | SOME t => t);
 
 fun is_poly thy (Datatype_Aux.DtType (name, dts)) =
-      (case lookup_size thy name of
-         NONE => false
-       | SOME _ => exists (is_poly thy) dts)
+      is_some (BNF_LFP_Size.lookup_size thy name) andalso exists (is_poly thy) dts
   | is_poly _ _ = true;
 
 fun constrs_of thy name =
@@ -66,7 +53,6 @@
       thy
     else
       let
-        val (rec_names1, rec_names2) = chop l rec_names;
         val recTs = Datatype_Aux.get_rec_types descr;
         val (recTs1, recTs2) = chop l recTs;
         val (_, (_, paramdts, _)) :: _ = descr;
@@ -82,8 +68,8 @@
         val param_size = AList.lookup op = param_size_fs;
 
         val extra_rewrites = descr |> map (#1 o snd) |> distinct op = |>
-          map_filter (Option.map snd o lookup_size thy) |> flat;
-        val extra_size = Option.map fst o lookup_size thy;
+          map_filter (Option.map (fst o snd) o BNF_LFP_Size.lookup_size thy) |> flat;
+        val extra_size = Option.map fst o BNF_LFP_Size.lookup_size thy;
 
         val (((size_names, size_fns), def_names), def_names') =
           recTs1 |> map (fn T as Type (s, _) =>
@@ -160,7 +146,7 @@
             size_def_thms @ size_def_thms' @ rec_rewrites @ extra_rewrites;
         val xs = map (fn i => "x" ^ string_of_int i) (1 upto length recTs2);
 
-        fun mk_unfolded_size_eq tab size_ofp fs (p as (x, T), r) =
+        fun mk_unfolded_size_eq tab size_ofp fs (p as (_, T), r) =
           HOLogic.mk_eq (app fs r $ Free p,
             the (size_of_type tab extra_size size_ofp T) $ Free p);
 
@@ -181,7 +167,7 @@
           let
             val Ts = map (Datatype_Aux.typ_of_dtyp descr) cargs;
             val tnames = Name.variant_list f_names (Datatype_Prop.make_tnames Ts);
-            val ts = map_filter (fn (sT as (s, T), dt) =>
+            val ts = map_filter (fn (sT as (_, T), dt) =>
               Option.map (fn sz => sz $ Free sT)
                 (if p dt then size_of_type size_of extra_size size_ofp T
                  else NONE)) (tnames ~~ Ts ~~ cargs)
@@ -220,12 +206,13 @@
               [(size_eqns, [])])];
 
       in
-        Data.map (fold (Symtab.update_new o apsnd (rpair size_thms))
-          (new_type_names ~~ size_names)) thy''
+        fold2 (fn new_type_name => fn size_name =>
+            BNF_LFP_Size.register_size new_type_name size_name [] size_thms)
+          new_type_names size_names thy''
       end
   end;
 
-fun add_size_thms config (new_type_names as name :: _) thy =
+fun add_size_thms _ (new_type_names as name :: _) thy =
   let
     val info as {descr, ...} = Datatype_Data.the_info thy name;
     val prefix = space_implode "_" (map Long_Name.base_name new_type_names);
@@ -241,8 +228,6 @@
       |> Sign.restore_naming thy
   end;
 
-val size_thms = snd oo (the oo lookup_size);
-
 val setup = Datatype_Data.interpretation add_size_thms;
 
 end;
--- a/src/HOL/Wellfounded.thy	Wed Apr 23 10:23:26 2014 +0200
+++ b/src/HOL/Wellfounded.thy	Wed Apr 23 10:23:27 2014 +0200
@@ -848,20 +848,6 @@
 done
 
 
-subsection {* size of a datatype value *}
-
-ML_file "Tools/Function/size.ML"
-setup Size.setup
-
-lemma size_bool [code]:
-  "size (b\<Colon>bool) = 0" by (cases b) auto
-
-lemma nat_size [simp, code]: "size (n\<Colon>nat) = n"
-  by (induct n) simp_all
-
-declare prod.size [no_atp]
-
-
 hide_const (open) acc accp
 
 end