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]: |
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: |
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 |