merged
authorhaftmann
Wed, 17 Feb 2010 11:21:59 +0100
changeset 3516558b9503a7f9a
parent 35162 ea99593b44a5
parent 35164 8e3b8b5f1e96
child 35166 a57ef2cd2236
child 35186 bb64d089c643
merged
     1.1 --- a/src/HOL/ex/Execute_Choice.thy	Wed Feb 17 11:01:01 2010 +0100
     1.2 +++ b/src/HOL/ex/Execute_Choice.thy	Wed Feb 17 11:21:59 2010 +0100
     1.3 @@ -6,9 +6,18 @@
     1.4  imports Main AssocList
     1.5  begin
     1.6  
     1.7 -definition valuesum :: "('a, 'b :: comm_monoid_add) mapping \<Rightarrow> 'b" where
     1.8 +text {*
     1.9 +  A trivial example:
    1.10 +*}
    1.11 +
    1.12 +definition valuesum :: "('a, 'b :: ab_group_add) mapping \<Rightarrow> 'b" where
    1.13    "valuesum m = (\<Sum>k \<in> Mapping.keys m. the (Mapping.lookup m k))"
    1.14  
    1.15 +text {*
    1.16 +  Not that instead of defining @{term valuesum} with choice, we define it
    1.17 +  directly and derive a description involving choice afterwards:
    1.18 +*}
    1.19 +
    1.20  lemma valuesum_rec:
    1.21    assumes fin: "finite (dom (Mapping.lookup m))"
    1.22    shows "valuesum m = (if Mapping.is_empty m then 0 else
    1.23 @@ -35,30 +44,59 @@
    1.24    then show ?thesis by (simp add: keys_def valuesum_def is_empty_def)
    1.25  qed
    1.26  
    1.27 +text {*
    1.28 +  In the context of the else-branch we can show that the exact choice is
    1.29 +  irrelvant; in practice, finding this point where choice becomes irrelevant is the
    1.30 +  most difficult thing!
    1.31 +*}
    1.32 +
    1.33 +lemma valuesum_choice:
    1.34 +  "finite (Mapping.keys M) \<Longrightarrow> x \<in> Mapping.keys M \<Longrightarrow> y \<in> Mapping.keys M \<Longrightarrow>
    1.35 +    the (Mapping.lookup M x) + valuesum (Mapping.delete x M) =
    1.36 +    the (Mapping.lookup M y) + valuesum (Mapping.delete y M)"
    1.37 +  by (simp add: valuesum_def keys_def setsum_diff)
    1.38 +
    1.39 +text {*
    1.40 +  Given @{text valuesum_rec} as initial description, we stepwise refine it to something executable;
    1.41 +  first, we formally insert the constructor @{term AList} and split the one equation into two,
    1.42 +  where the second one provides the necessary context:
    1.43 +*}
    1.44 +
    1.45  lemma valuesum_rec_AList:
    1.46 -  "valuesum (AList []) = 0"
    1.47 -  "valuesum (AList (x # xs)) = (let l = (SOME l. l \<in> Mapping.keys (AList (x # xs))) in
    1.48 +  shows [code]: "valuesum (AList []) = 0"
    1.49 +  and "valuesum (AList (x # xs)) = (let l = (SOME l. l \<in> Mapping.keys (AList (x # xs))) in
    1.50      the (Mapping.lookup (AList (x # xs)) l) + valuesum (Mapping.delete l (AList (x # xs))))"
    1.51    by (simp_all add: valuesum_rec finite_dom_map_of is_empty_AList)
    1.52  
    1.53 -axioms
    1.54 -  FIXME: "x \<in> A \<Longrightarrow> y \<in> A \<Longrightarrow> C x = C y"
    1.55 +text {*
    1.56 +  As a side effect the precondition disappears (but note this has nothing to do with choice!).
    1.57 +  The first equation deals with the uncritical empty case and can already be used for code generation.
    1.58  
    1.59 -lemma aux: "(SOME l. l \<in> Mapping.keys (AList (x # xs))) = fst (hd (x # xs))"
    1.60 -proof (rule FIXME)
    1.61 -  show "fst (hd (x # xs)) \<in> Mapping.keys (AList (x # xs))"
    1.62 -    by (simp add: keys_AList)
    1.63 -  show "(SOME l. l \<in> Mapping.keys (AList (x # xs))) \<in> Mapping.keys (AList (x # xs))"
    1.64 -    apply (rule someI) apply (simp add: keys_AList) apply auto
    1.65 -    done
    1.66 -qed
    1.67 +  Using @{text valuesum_choice}, we are able to prove an executable version of @{term valuesum}:
    1.68 +*}
    1.69  
    1.70  lemma valuesum_rec_exec [code]:
    1.71 -  "valuesum (AList []) = 0"
    1.72    "valuesum (AList (x # xs)) = (let l = fst (hd (x # xs)) in
    1.73      the (Mapping.lookup (AList (x # xs)) l) + valuesum (Mapping.delete l (AList (x # xs))))"
    1.74 -  by (simp_all add: valuesum_rec_AList aux)
    1.75 +proof -
    1.76 +  let ?M = "AList (x # xs)"
    1.77 +  let ?l1 = "(SOME l. l \<in> Mapping.keys ?M)"
    1.78 +  let ?l2 = "fst (hd (x # xs))"
    1.79 +  have "finite (Mapping.keys ?M)" by (simp add: keys_AList)
    1.80 +  moreover have "?l1 \<in> Mapping.keys ?M"
    1.81 +    by (rule someI) (auto simp add: keys_AList)
    1.82 +  moreover have "?l2 \<in> Mapping.keys ?M"
    1.83 +    by (simp add: keys_AList)
    1.84 +  ultimately have "the (Mapping.lookup ?M ?l1) + valuesum (Mapping.delete ?l1 ?M) =
    1.85 +    the (Mapping.lookup ?M ?l2) + valuesum (Mapping.delete ?l2 ?M)"
    1.86 +    by (rule valuesum_choice)
    1.87 +  then show ?thesis by (simp add: valuesum_rec_AList)
    1.88 +qed
    1.89 +  
    1.90 +text {*
    1.91 +  See how it works:
    1.92 +*}
    1.93  
    1.94 -value "valuesum (AList [(''abc'', (42::nat)), (''def'', 1705)])"
    1.95 +value "valuesum (AList [(''abc'', (42::int)), (''def'', 1705)])"
    1.96  
    1.97  end
     2.1 --- a/src/HOL/ex/ROOT.ML	Wed Feb 17 11:01:01 2010 +0100
     2.2 +++ b/src/HOL/ex/ROOT.ML	Wed Feb 17 11:21:59 2010 +0100
     2.3 @@ -66,7 +66,8 @@
     2.4    "Refute_Examples",
     2.5    "Quickcheck_Examples",
     2.6    "Landau",
     2.7 -  "Execute_Choice"
     2.8 +  "Execute_Choice",
     2.9 +  "Summation"
    2.10  ];
    2.11  
    2.12  HTML.with_charset "utf-8" (no_document use_thys)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/HOL/ex/Summation.thy	Wed Feb 17 11:21:59 2010 +0100
     3.3 @@ -0,0 +1,107 @@
     3.4 +(* Author: Florian Haftmann, TU Muenchen *)
     3.5 +
     3.6 +header {* Some basic facts about discrete summation *}
     3.7 +
     3.8 +theory Summation
     3.9 +imports Main
    3.10 +begin
    3.11 +
    3.12 +text {* Auxiliary. *}
    3.13 +
    3.14 +lemma add_setsum_orient:
    3.15 +  "setsum f {k..<j} + setsum f {l..<k} = setsum f {l..<k} + setsum f {k..<j}"
    3.16 +  by (fact plus.commute)
    3.17 +
    3.18 +lemma add_setsum_int:
    3.19 +  fixes j k l :: int
    3.20 +  shows "j < k \<Longrightarrow> k < l \<Longrightarrow> setsum f {j..<k} + setsum f {k..<l} = setsum f {j..<l}"
    3.21 +  by (simp_all add: setsum_Un_Int [symmetric] ivl_disj_un)
    3.22 +
    3.23 +text {* The shift operator. *}
    3.24 +
    3.25 +definition \<Delta> :: "(int \<Rightarrow> 'a\<Colon>ab_group_add) \<Rightarrow> int \<Rightarrow> 'a" where
    3.26 +  "\<Delta> f k = f (k + 1) - f k"
    3.27 +
    3.28 +lemma \<Delta>_shift:
    3.29 +  "\<Delta> (\<lambda>k. l + f k) = \<Delta> f"
    3.30 +  by (simp add: \<Delta>_def expand_fun_eq)
    3.31 +
    3.32 +lemma \<Delta>_same_shift:
    3.33 +  assumes "\<Delta> f = \<Delta> g"
    3.34 +  shows "\<exists>l. (op +) l \<circ> f = g"
    3.35 +proof -
    3.36 +  fix k
    3.37 +  from assms have "\<And>k. \<Delta> f k = \<Delta> g k" by simp
    3.38 +  then have k_incr: "\<And>k. f (k + 1) - g (k + 1) = f k - g k"
    3.39 +    by (simp add: \<Delta>_def algebra_simps)
    3.40 +  then have "\<And>k. f ((k - 1) + 1) - g ((k - 1) + 1) = f (k - 1) - g (k - 1)"
    3.41 +    by blast
    3.42 +  then have k_decr: "\<And>k. f (k - 1) - g (k - 1) = f k - g k"
    3.43 +    by simp
    3.44 +  have "\<And>k. f k - g k = f 0 - g 0"
    3.45 +  proof -
    3.46 +    fix k
    3.47 +    show "f k - g k = f 0 - g 0"
    3.48 +      by (induct k rule: int_induct) (simp_all add: k_incr k_decr)
    3.49 +  qed
    3.50 +  then have "\<And>k. ((op +) (g 0 - f 0) \<circ> f) k = g k"
    3.51 +    by (simp add: algebra_simps)
    3.52 +  then have "(op +) (g 0 - f 0) \<circ> f = g" ..
    3.53 +  then show ?thesis ..
    3.54 +qed
    3.55 +
    3.56 +text {* The formal sum operator. *}
    3.57 +
    3.58 +definition \<Sigma> :: "(int \<Rightarrow> 'a\<Colon>ab_group_add) \<Rightarrow> int \<Rightarrow> int \<Rightarrow> 'a" where
    3.59 +  "\<Sigma> f j l = (if j < l then setsum f {j..<l}
    3.60 +    else if j > l then - setsum f {l..<j}
    3.61 +    else 0)"
    3.62 +
    3.63 +lemma \<Sigma>_same [simp]:
    3.64 +  "\<Sigma> f j j = 0"
    3.65 +  by (simp add: \<Sigma>_def)
    3.66 +
    3.67 +lemma \<Sigma>_positive:
    3.68 +  "j < l \<Longrightarrow> \<Sigma> f j l = setsum f {j..<l}"
    3.69 +  by (simp add: \<Sigma>_def)
    3.70 +
    3.71 +lemma \<Sigma>_negative:
    3.72 +  "j > l \<Longrightarrow> \<Sigma> f j l = - \<Sigma> f l j"
    3.73 +  by (simp add: \<Sigma>_def)
    3.74 +
    3.75 +lemma add_\<Sigma>:
    3.76 +  "\<Sigma> f j k + \<Sigma> f k l = \<Sigma> f j l"
    3.77 +  by (simp add: \<Sigma>_def algebra_simps add_setsum_int)
    3.78 +   (simp_all add: add_setsum_orient [of f k j l]
    3.79 +      add_setsum_orient [of f j l k]
    3.80 +      add_setsum_orient [of f j k l] add_setsum_int)
    3.81 +
    3.82 +lemma \<Sigma>_incr_upper:
    3.83 +  "\<Sigma> f j (l + 1) = \<Sigma> f j l + f l"
    3.84 +proof -
    3.85 +  have "{l..<l+1} = {l}" by auto
    3.86 +  then have "\<Sigma> f l (l + 1) = f l" by (simp add: \<Sigma>_def)
    3.87 +  moreover have "\<Sigma> f j (l + 1) = \<Sigma> f j l + \<Sigma> f l (l + 1)" by (simp add: add_\<Sigma>)
    3.88 +  ultimately show ?thesis by simp
    3.89 +qed
    3.90 +
    3.91 +text {* Fundamental lemmas: The relation between @{term \<Delta>} and @{term \<Sigma>}. *}
    3.92 +
    3.93 +lemma \<Delta>_\<Sigma>:
    3.94 +  "\<Delta> (\<Sigma> f j) = f"
    3.95 +proof
    3.96 +  fix k
    3.97 +  show "\<Delta> (\<Sigma> f j) k = f k"
    3.98 +    by (simp add: \<Delta>_def \<Sigma>_incr_upper)
    3.99 +qed
   3.100 +
   3.101 +lemma \<Sigma>_\<Delta>:
   3.102 +  "\<Sigma> (\<Delta> f) j l = f l - f j"
   3.103 +proof -
   3.104 +  from \<Delta>_\<Sigma> have "\<Delta> (\<Sigma> (\<Delta> f) j) = \<Delta> f" .
   3.105 +  then obtain k where "(op +) k \<circ> \<Sigma> (\<Delta> f) j = f" by (blast dest: \<Delta>_same_shift)
   3.106 +  then have "\<And>q. f q = k + \<Sigma> (\<Delta> f) j q" by (simp add: expand_fun_eq)
   3.107 +  then show ?thesis by simp
   3.108 +qed
   3.109 +
   3.110 +end