src/HOL/Finite_Set.thy
changeset 19535 e4fdeb32eadf
parent 19363 667b5ea637dd
child 19793 14fdd2a3d117
equal deleted inserted replaced
19534:1724ec4032c5 19535:e4fdeb32eadf
   801 
   801 
   802 constdefs
   802 constdefs
   803   setsum :: "('a => 'b) => 'a set => 'b::comm_monoid_add"
   803   setsum :: "('a => 'b) => 'a set => 'b::comm_monoid_add"
   804   "setsum f A == if finite A then fold (op +) f 0 A else 0"
   804   "setsum f A == if finite A then fold (op +) f 0 A else 0"
   805 
   805 
       
   806 abbreviation
       
   807   Setsum  ("\<Sum>_" [1000] 999)
       
   808   "\<Sum>A == setsum (%x. x) A"
       
   809 
   806 text{* Now: lot's of fancy syntax. First, @{term "setsum (%x. e) A"} is
   810 text{* Now: lot's of fancy syntax. First, @{term "setsum (%x. e) A"} is
   807 written @{text"\<Sum>x\<in>A. e"}. *}
   811 written @{text"\<Sum>x\<in>A. e"}. *}
   808 
   812 
   809 syntax
   813 syntax
   810   "_setsum" :: "pttrn => 'a set => 'b => 'b::comm_monoid_add"    ("(3SUM _:_. _)" [0, 51, 10] 10)
   814   "_setsum" :: "pttrn => 'a set => 'b => 'b::comm_monoid_add"    ("(3SUM _:_. _)" [0, 51, 10] 10)
   829 
   833 
   830 translations
   834 translations
   831   "SUM x|P. t" => "setsum (%x. t) {x. P}"
   835   "SUM x|P. t" => "setsum (%x. t) {x. P}"
   832   "\<Sum>x|P. t" => "setsum (%x. t) {x. P}"
   836   "\<Sum>x|P. t" => "setsum (%x. t) {x. P}"
   833 
   837 
   834 text{* Finally we abbreviate @{term"\<Sum>x\<in>A. x"} by @{text"\<Sum>A"}. *}
       
   835 
       
   836 syntax
       
   837   "_Setsum" :: "'a set => 'a::comm_monoid_mult"  ("\<Sum>_" [1000] 999)
       
   838 
       
   839 parse_translation {*
       
   840   let
       
   841     fun Setsum_tr [A] = Syntax.const "setsum" $ Term.absdummy (dummyT, Bound 0) $ A
       
   842   in [("_Setsum", Setsum_tr)] end;
       
   843 *}
       
   844 
       
   845 print_translation {*
   838 print_translation {*
   846 let
   839 let
   847   fun setsum_tr' [Abs(_,_,Bound 0), A] = Syntax.const "_Setsum" $ A
   840   fun setsum_tr' [Abs(x,Tx,t), Const ("Collect",_) $ Abs(y,Ty,P)] = 
   848     | setsum_tr' [Abs(x,Tx,t), Const ("Collect",_) $ Abs(y,Ty,P)] = 
   841     if x<>y then raise Match
   849        if x<>y then raise Match
   842     else let val x' = Syntax.mark_bound x
   850        else let val x' = Syntax.mark_bound x
   843              val t' = subst_bound(x',t)
   851                 val t' = subst_bound(x',t)
   844              val P' = subst_bound(x',P)
   852                 val P' = subst_bound(x',P)
   845          in Syntax.const "_qsetsum" $ Syntax.mark_bound x $ P' $ t' end
   853             in Syntax.const "_qsetsum" $ Syntax.mark_bound x $ P' $ t' end
   846 in [("setsum", setsum_tr')] end
   854 in
       
   855 [("setsum", setsum_tr')]
       
   856 end
       
   857 *}
   847 *}
       
   848 
   858 
   849 
   859 lemma setsum_empty [simp]: "setsum f {} = 0"
   850 lemma setsum_empty [simp]: "setsum f {} = 0"
   860   by (simp add: setsum_def)
   851   by (simp add: setsum_def)
   861 
   852 
   862 lemma setsum_insert [simp]:
   853 lemma setsum_insert [simp]:
   993   done
   984   done
   994 
   985 
   995 (* By Jeremy Siek: *)
   986 (* By Jeremy Siek: *)
   996 
   987 
   997 lemma setsum_diff_nat: 
   988 lemma setsum_diff_nat: 
   998   assumes finB: "finite B"
   989   assumes "finite B"
   999   shows "B \<subseteq> A \<Longrightarrow> (setsum f (A - B) :: nat) = (setsum f A) - (setsum f B)"
   990     and "B \<subseteq> A"
  1000 using finB
   991   shows "(setsum f (A - B) :: nat) = (setsum f A) - (setsum f B)"
  1001 proof (induct)
   992   using prems
       
   993 proof induct
  1002   show "setsum f (A - {}) = (setsum f A) - (setsum f {})" by simp
   994   show "setsum f (A - {}) = (setsum f A) - (setsum f {})" by simp
  1003 next
   995 next
  1004   fix F x assume finF: "finite F" and xnotinF: "x \<notin> F"
   996   fix F x assume finF: "finite F" and xnotinF: "x \<notin> F"
  1005     and xFinA: "insert x F \<subseteq> A"
   997     and xFinA: "insert x F \<subseteq> A"
  1006     and IH: "F \<subseteq> A \<Longrightarrow> setsum f (A - F) = setsum f A - setsum f F"
   998     and IH: "F \<subseteq> A \<Longrightarrow> setsum f (A - F) = setsum f A - setsum f F"
  1024   assumes le: "finite A" "B \<subseteq> A"
  1016   assumes le: "finite A" "B \<subseteq> A"
  1025   shows "setsum f (A - B) = setsum f A - ((setsum f B)::('a::ab_group_add))"
  1017   shows "setsum f (A - B) = setsum f A - ((setsum f B)::('a::ab_group_add))"
  1026 proof -
  1018 proof -
  1027   from le have finiteB: "finite B" using finite_subset by auto
  1019   from le have finiteB: "finite B" using finite_subset by auto
  1028   show ?thesis using finiteB le
  1020   show ?thesis using finiteB le
  1029     proof (induct)
  1021   proof (induct)
  1030       case empty
  1022     case empty
  1031       thus ?case by auto
  1023     thus ?case by auto
  1032     next
  1024   next
  1033       case (insert x F)
  1025     case (insert x F)
  1034       thus ?case using le finiteB 
  1026     thus ?case using le finiteB 
  1035 	by (simp add: Diff_insert[where a=x and B=F] setsum_diff1 insert_absorb)
  1027       by (simp add: Diff_insert[where a=x and B=F] setsum_diff1 insert_absorb)
  1036     qed
  1028   qed
  1037   qed
  1029 qed
  1038 
  1030 
  1039 lemma setsum_mono:
  1031 lemma setsum_mono:
  1040   assumes le: "\<And>i. i\<in>K \<Longrightarrow> f (i::'a) \<le> ((g i)::('b::{comm_monoid_add, pordered_ab_semigroup_add}))"
  1032   assumes le: "\<And>i. i\<in>K \<Longrightarrow> f (i::'a) \<le> ((g i)::('b::{comm_monoid_add, pordered_ab_semigroup_add}))"
  1041   shows "(\<Sum>i\<in>K. f i) \<le> (\<Sum>i\<in>K. g i)"
  1033   shows "(\<Sum>i\<in>K. f i) \<le> (\<Sum>i\<in>K. g i)"
  1042 proof (cases "finite K")
  1034 proof (cases "finite K")
  1043   case True
  1035   case True
  1044   thus ?thesis using le
  1036   thus ?thesis using le
  1045   proof (induct)
  1037   proof induct
  1046     case empty
  1038     case empty
  1047     thus ?case by simp
  1039     thus ?case by simp
  1048   next
  1040   next
  1049     case insert
  1041     case insert
  1050     thus ?case using add_mono 
  1042     thus ?case using add_mono by fastsimp
  1051       by force
       
  1052   qed
  1043   qed
  1053 next
  1044 next
  1054   case False
  1045   case False
  1055   thus ?thesis
  1046   thus ?thesis
  1056     by (simp add: setsum_def)
  1047     by (simp add: setsum_def)
  1057 qed
  1048 qed
  1058 
  1049 
  1059 lemma setsum_strict_mono:
  1050 lemma setsum_strict_mono:
  1060 fixes f :: "'a \<Rightarrow> 'b::{pordered_cancel_ab_semigroup_add,comm_monoid_add}"
  1051   fixes f :: "'a \<Rightarrow> 'b::{pordered_cancel_ab_semigroup_add,comm_monoid_add}"
  1061 assumes fin_ne: "finite A"  "A \<noteq> {}"
  1052   assumes "finite A"  "A \<noteq> {}"
  1062 shows "(!!x. x:A \<Longrightarrow> f x < g x) \<Longrightarrow> setsum f A < setsum g A"
  1053     and "!!x. x:A \<Longrightarrow> f x < g x"
  1063 using fin_ne
  1054   shows "setsum f A < setsum g A"
       
  1055   using prems
  1064 proof (induct rule: finite_ne_induct)
  1056 proof (induct rule: finite_ne_induct)
  1065   case singleton thus ?case by simp
  1057   case singleton thus ?case by simp
  1066 next
  1058 next
  1067   case insert thus ?case by (auto simp: add_strict_mono)
  1059   case insert thus ?case by (auto simp: add_strict_mono)
  1068 qed
  1060 qed
  1069 
  1061 
  1070 lemma setsum_negf:
  1062 lemma setsum_negf:
  1071  "setsum (%x. - (f x)::'a::ab_group_add) A = - setsum f A"
  1063   "setsum (%x. - (f x)::'a::ab_group_add) A = - setsum f A"
  1072 proof (cases "finite A")
  1064 proof (cases "finite A")
  1073   case True thus ?thesis by (induct set: Finites, auto)
  1065   case True thus ?thesis by (induct set: Finites, auto)
  1074 next
  1066 next
  1075   case False thus ?thesis by (simp add: setsum_def)
  1067   case False thus ?thesis by (simp add: setsum_def)
  1076 qed
  1068 qed
  1077 
  1069 
  1078 lemma setsum_subtractf:
  1070 lemma setsum_subtractf:
  1079  "setsum (%x. ((f x)::'a::ab_group_add) - g x) A =
  1071   "setsum (%x. ((f x)::'a::ab_group_add) - g x) A =
  1080   setsum f A - setsum g A"
  1072     setsum f A - setsum g A"
  1081 proof (cases "finite A")
  1073 proof (cases "finite A")
  1082   case True thus ?thesis by (simp add: diff_minus setsum_addf setsum_negf)
  1074   case True thus ?thesis by (simp add: diff_minus setsum_addf setsum_negf)
  1083 next
  1075 next
  1084   case False thus ?thesis by (simp add: setsum_def)
  1076   case False thus ?thesis by (simp add: setsum_def)
  1085 qed
  1077 qed
  1086 
  1078 
  1087 lemma setsum_nonneg:
  1079 lemma setsum_nonneg:
  1088 assumes nn: "\<forall>x\<in>A. (0::'a::{pordered_ab_semigroup_add,comm_monoid_add}) \<le> f x"
  1080   assumes nn: "\<forall>x\<in>A. (0::'a::{pordered_ab_semigroup_add,comm_monoid_add}) \<le> f x"
  1089 shows "0 \<le> setsum f A"
  1081   shows "0 \<le> setsum f A"
  1090 proof (cases "finite A")
  1082 proof (cases "finite A")
  1091   case True thus ?thesis using nn
  1083   case True thus ?thesis using nn
  1092   apply (induct set: Finites, auto)
  1084   proof (induct)
  1093   apply (subgoal_tac "0 + 0 \<le> f x + setsum f F", simp)
  1085     case empty then show ?case by simp
  1094   apply (blast intro: add_mono)
  1086   next
  1095   done
  1087     case (insert x F)
       
  1088     then have "0 + 0 \<le> f x + setsum f F" by (blast intro: add_mono)
       
  1089     with insert show ?case by simp
       
  1090   qed
  1096 next
  1091 next
  1097   case False thus ?thesis by (simp add: setsum_def)
  1092   case False thus ?thesis by (simp add: setsum_def)
  1098 qed
  1093 qed
  1099 
  1094 
  1100 lemma setsum_nonpos:
  1095 lemma setsum_nonpos:
  1101 assumes np: "\<forall>x\<in>A. f x \<le> (0::'a::{pordered_ab_semigroup_add,comm_monoid_add})"
  1096   assumes np: "\<forall>x\<in>A. f x \<le> (0::'a::{pordered_ab_semigroup_add,comm_monoid_add})"
  1102 shows "setsum f A \<le> 0"
  1097   shows "setsum f A \<le> 0"
  1103 proof (cases "finite A")
  1098 proof (cases "finite A")
  1104   case True thus ?thesis using np
  1099   case True thus ?thesis using np
  1105   apply (induct set: Finites, auto)
  1100   proof (induct)
  1106   apply (subgoal_tac "f x + setsum f F \<le> 0 + 0", simp)
  1101     case empty then show ?case by simp
  1107   apply (blast intro: add_mono)
  1102   next
  1108   done
  1103     case (insert x F)
       
  1104     then have "f x + setsum f F \<le> 0 + 0" by (blast intro: add_mono)
       
  1105     with insert show ?case by simp
       
  1106   qed
  1109 next
  1107 next
  1110   case False thus ?thesis by (simp add: setsum_def)
  1108   case False thus ?thesis by (simp add: setsum_def)
  1111 qed
  1109 qed
  1112 
  1110 
  1113 lemma setsum_mono2:
  1111 lemma setsum_mono2:
  1275 
  1273 
  1276 constdefs
  1274 constdefs
  1277   setprod :: "('a => 'b) => 'a set => 'b::comm_monoid_mult"
  1275   setprod :: "('a => 'b) => 'a set => 'b::comm_monoid_mult"
  1278   "setprod f A == if finite A then fold (op *) f 1 A else 1"
  1276   "setprod f A == if finite A then fold (op *) f 1 A else 1"
  1279 
  1277 
       
  1278 abbreviation
       
  1279   Setprod  ("\<Prod>_" [1000] 999)
       
  1280   "\<Prod>A == setprod (%x. x) A"
       
  1281 
  1280 syntax
  1282 syntax
  1281   "_setprod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ("(3PROD _:_. _)" [0, 51, 10] 10)
  1283   "_setprod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ("(3PROD _:_. _)" [0, 51, 10] 10)
  1282 syntax (xsymbols)
  1284 syntax (xsymbols)
  1283   "_setprod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ("(3\<Prod>_\<in>_. _)" [0, 51, 10] 10)
  1285   "_setprod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ("(3\<Prod>_\<in>_. _)" [0, 51, 10] 10)
  1284 syntax (HTML output)
  1286 syntax (HTML output)
  1299   "_qsetprod" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a" ("(3\<Prod>_ | (_)./ _)" [0,0,10] 10)
  1301   "_qsetprod" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a" ("(3\<Prod>_ | (_)./ _)" [0,0,10] 10)
  1300 
  1302 
  1301 translations
  1303 translations
  1302   "PROD x|P. t" => "setprod (%x. t) {x. P}"
  1304   "PROD x|P. t" => "setprod (%x. t) {x. P}"
  1303   "\<Prod>x|P. t" => "setprod (%x. t) {x. P}"
  1305   "\<Prod>x|P. t" => "setprod (%x. t) {x. P}"
  1304 
       
  1305 text{* Finally we abbreviate @{term"\<Prod>x\<in>A. x"} by @{text"\<Prod>A"}. *}
       
  1306 
       
  1307 syntax
       
  1308   "_Setprod" :: "'a set => 'a::comm_monoid_mult"  ("\<Prod>_" [1000] 999)
       
  1309 
       
  1310 parse_translation {*
       
  1311   let
       
  1312     fun Setprod_tr [A] = Syntax.const "setprod" $ Abs ("", dummyT, Bound 0) $ A
       
  1313   in [("_Setprod", Setprod_tr)] end;
       
  1314 *}
       
  1315 print_translation {*
       
  1316 let fun setprod_tr' [Abs(x,Tx,t), A] =
       
  1317     if t = Bound 0 then Syntax.const "_Setprod" $ A else raise Match
       
  1318 in
       
  1319 [("setprod", setprod_tr')]
       
  1320 end
       
  1321 *}
       
  1322 
  1306 
  1323 
  1307 
  1324 lemma setprod_empty [simp]: "setprod f {} = 1"
  1308 lemma setprod_empty [simp]: "setprod f {} = 1"
  1325   by (auto simp add: setprod_def)
  1309   by (auto simp add: setprod_def)
  1326 
  1310