src/HOL/Groups_Big.thy
changeset 64272 f76b6dda2e56
parent 64267 b9a1486e79be
child 64979 20a623d03d71
equal deleted inserted replaced
64269:c939cc16b605 64272:f76b6dda2e56
  1049 subsection \<open>Generalized product over a set\<close>
  1049 subsection \<open>Generalized product over a set\<close>
  1050 
  1050 
  1051 context comm_monoid_mult
  1051 context comm_monoid_mult
  1052 begin
  1052 begin
  1053 
  1053 
  1054 sublocale setprod: comm_monoid_set times 1
  1054 sublocale prod: comm_monoid_set times 1
  1055   defines setprod = setprod.F ..
  1055   defines prod = prod.F ..
  1056 
  1056 
  1057 abbreviation Setprod ("\<Prod>_" [1000] 999)
  1057 abbreviation Prod ("\<Prod>_" [1000] 999)
  1058   where "\<Prod>A \<equiv> setprod (\<lambda>x. x) A"
  1058   where "\<Prod>A \<equiv> prod (\<lambda>x. x) A"
  1059 
  1059 
  1060 end
  1060 end
  1061 
  1061 
  1062 syntax (ASCII)
  1062 syntax (ASCII)
  1063   "_setprod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ("(4PROD _:_./ _)" [0, 51, 10] 10)
  1063   "_prod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ("(4PROD _:_./ _)" [0, 51, 10] 10)
  1064 syntax
  1064 syntax
  1065   "_setprod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ("(2\<Prod>_\<in>_./ _)" [0, 51, 10] 10)
  1065   "_prod" :: "pttrn => 'a set => 'b => 'b::comm_monoid_mult"  ("(2\<Prod>_\<in>_./ _)" [0, 51, 10] 10)
  1066 translations \<comment> \<open>Beware of argument permutation!\<close>
  1066 translations \<comment> \<open>Beware of argument permutation!\<close>
  1067   "\<Prod>i\<in>A. b" == "CONST setprod (\<lambda>i. b) A"
  1067   "\<Prod>i\<in>A. b" == "CONST prod (\<lambda>i. b) A"
  1068 
  1068 
  1069 text \<open>Instead of @{term"\<Prod>x\<in>{x. P}. e"} we introduce the shorter \<open>\<Prod>x|P. e\<close>.\<close>
  1069 text \<open>Instead of @{term"\<Prod>x\<in>{x. P}. e"} we introduce the shorter \<open>\<Prod>x|P. e\<close>.\<close>
  1070 
  1070 
  1071 syntax (ASCII)
  1071 syntax (ASCII)
  1072   "_qsetprod" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a"  ("(4PROD _ |/ _./ _)" [0, 0, 10] 10)
  1072   "_qprod" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a"  ("(4PROD _ |/ _./ _)" [0, 0, 10] 10)
  1073 syntax
  1073 syntax
  1074   "_qsetprod" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a"  ("(2\<Prod>_ | (_)./ _)" [0, 0, 10] 10)
  1074   "_qprod" :: "pttrn \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a"  ("(2\<Prod>_ | (_)./ _)" [0, 0, 10] 10)
  1075 translations
  1075 translations
  1076   "\<Prod>x|P. t" => "CONST setprod (\<lambda>x. t) {x. P}"
  1076   "\<Prod>x|P. t" => "CONST prod (\<lambda>x. t) {x. P}"
  1077 
  1077 
  1078 context comm_monoid_mult
  1078 context comm_monoid_mult
  1079 begin
  1079 begin
  1080 
  1080 
  1081 lemma setprod_dvd_setprod: "(\<And>a. a \<in> A \<Longrightarrow> f a dvd g a) \<Longrightarrow> setprod f A dvd setprod g A"
  1081 lemma prod_dvd_prod: "(\<And>a. a \<in> A \<Longrightarrow> f a dvd g a) \<Longrightarrow> prod f A dvd prod g A"
  1082 proof (induct A rule: infinite_finite_induct)
  1082 proof (induct A rule: infinite_finite_induct)
  1083   case infinite
  1083   case infinite
  1084   then show ?case by (auto intro: dvdI)
  1084   then show ?case by (auto intro: dvdI)
  1085 next
  1085 next
  1086   case empty
  1086   case empty
  1087   then show ?case by (auto intro: dvdI)
  1087   then show ?case by (auto intro: dvdI)
  1088 next
  1088 next
  1089   case (insert a A)
  1089   case (insert a A)
  1090   then have "f a dvd g a" and "setprod f A dvd setprod g A"
  1090   then have "f a dvd g a" and "prod f A dvd prod g A"
  1091     by simp_all
  1091     by simp_all
  1092   then obtain r s where "g a = f a * r" and "setprod g A = setprod f A * s"
  1092   then obtain r s where "g a = f a * r" and "prod g A = prod f A * s"
  1093     by (auto elim!: dvdE)
  1093     by (auto elim!: dvdE)
  1094   then have "g a * setprod g A = f a * setprod f A * (r * s)"
  1094   then have "g a * prod g A = f a * prod f A * (r * s)"
  1095     by (simp add: ac_simps)
  1095     by (simp add: ac_simps)
  1096   with insert.hyps show ?case
  1096   with insert.hyps show ?case
  1097     by (auto intro: dvdI)
  1097     by (auto intro: dvdI)
  1098 qed
  1098 qed
  1099 
  1099 
  1100 lemma setprod_dvd_setprod_subset: "finite B \<Longrightarrow> A \<subseteq> B \<Longrightarrow> setprod f A dvd setprod f B"
  1100 lemma prod_dvd_prod_subset: "finite B \<Longrightarrow> A \<subseteq> B \<Longrightarrow> prod f A dvd prod f B"
  1101   by (auto simp add: setprod.subset_diff ac_simps intro: dvdI)
  1101   by (auto simp add: prod.subset_diff ac_simps intro: dvdI)
  1102 
  1102 
  1103 end
  1103 end
  1104 
  1104 
  1105 
  1105 
  1106 subsubsection \<open>Properties in more restricted classes of structures\<close>
  1106 subsubsection \<open>Properties in more restricted classes of structures\<close>
  1107 
  1107 
  1108 context comm_semiring_1
  1108 context comm_semiring_1
  1109 begin
  1109 begin
  1110 
  1110 
  1111 lemma dvd_setprod_eqI [intro]:
  1111 lemma dvd_prod_eqI [intro]:
  1112   assumes "finite A" and "a \<in> A" and "b = f a"
  1112   assumes "finite A" and "a \<in> A" and "b = f a"
  1113   shows "b dvd setprod f A"
  1113   shows "b dvd prod f A"
  1114 proof -
  1114 proof -
  1115   from \<open>finite A\<close> have "setprod f (insert a (A - {a})) = f a * setprod f (A - {a})"
  1115   from \<open>finite A\<close> have "prod f (insert a (A - {a})) = f a * prod f (A - {a})"
  1116     by (intro setprod.insert) auto
  1116     by (intro prod.insert) auto
  1117   also from \<open>a \<in> A\<close> have "insert a (A - {a}) = A"
  1117   also from \<open>a \<in> A\<close> have "insert a (A - {a}) = A"
  1118     by blast
  1118     by blast
  1119   finally have "setprod f A = f a * setprod f (A - {a})" .
  1119   finally have "prod f A = f a * prod f (A - {a})" .
  1120   with \<open>b = f a\<close> show ?thesis
  1120   with \<open>b = f a\<close> show ?thesis
  1121     by simp
  1121     by simp
  1122 qed
  1122 qed
  1123 
  1123 
  1124 lemma dvd_setprodI [intro]: "finite A \<Longrightarrow> a \<in> A \<Longrightarrow> f a dvd setprod f A"
  1124 lemma dvd_prodI [intro]: "finite A \<Longrightarrow> a \<in> A \<Longrightarrow> f a dvd prod f A"
  1125   by auto
  1125   by auto
  1126 
  1126 
  1127 lemma setprod_zero:
  1127 lemma prod_zero:
  1128   assumes "finite A" and "\<exists>a\<in>A. f a = 0"
  1128   assumes "finite A" and "\<exists>a\<in>A. f a = 0"
  1129   shows "setprod f A = 0"
  1129   shows "prod f A = 0"
  1130   using assms
  1130   using assms
  1131 proof (induct A)
  1131 proof (induct A)
  1132   case empty
  1132   case empty
  1133   then show ?case by simp
  1133   then show ?case by simp
  1134 next
  1134 next
  1135   case (insert a A)
  1135   case (insert a A)
  1136   then have "f a = 0 \<or> (\<exists>a\<in>A. f a = 0)" by simp
  1136   then have "f a = 0 \<or> (\<exists>a\<in>A. f a = 0)" by simp
  1137   then have "f a * setprod f A = 0" by rule (simp_all add: insert)
  1137   then have "f a * prod f A = 0" by rule (simp_all add: insert)
  1138   with insert show ?case by simp
  1138   with insert show ?case by simp
  1139 qed
  1139 qed
  1140 
  1140 
  1141 lemma setprod_dvd_setprod_subset2:
  1141 lemma prod_dvd_prod_subset2:
  1142   assumes "finite B" and "A \<subseteq> B" and "\<And>a. a \<in> A \<Longrightarrow> f a dvd g a"
  1142   assumes "finite B" and "A \<subseteq> B" and "\<And>a. a \<in> A \<Longrightarrow> f a dvd g a"
  1143   shows "setprod f A dvd setprod g B"
  1143   shows "prod f A dvd prod g B"
  1144 proof -
  1144 proof -
  1145   from assms have "setprod f A dvd setprod g A"
  1145   from assms have "prod f A dvd prod g A"
  1146     by (auto intro: setprod_dvd_setprod)
  1146     by (auto intro: prod_dvd_prod)
  1147   moreover from assms have "setprod g A dvd setprod g B"
  1147   moreover from assms have "prod g A dvd prod g B"
  1148     by (auto intro: setprod_dvd_setprod_subset)
  1148     by (auto intro: prod_dvd_prod_subset)
  1149   ultimately show ?thesis by (rule dvd_trans)
  1149   ultimately show ?thesis by (rule dvd_trans)
  1150 qed
  1150 qed
  1151 
  1151 
  1152 end
  1152 end
  1153 
  1153 
  1154 lemma (in semidom) setprod_zero_iff [simp]:
  1154 lemma (in semidom) prod_zero_iff [simp]:
  1155   fixes f :: "'b \<Rightarrow> 'a"
  1155   fixes f :: "'b \<Rightarrow> 'a"
  1156   assumes "finite A"
  1156   assumes "finite A"
  1157   shows "setprod f A = 0 \<longleftrightarrow> (\<exists>a\<in>A. f a = 0)"
  1157   shows "prod f A = 0 \<longleftrightarrow> (\<exists>a\<in>A. f a = 0)"
  1158   using assms by (induct A) (auto simp: no_zero_divisors)
  1158   using assms by (induct A) (auto simp: no_zero_divisors)
  1159 
  1159 
  1160 lemma (in semidom_divide) setprod_diff1:
  1160 lemma (in semidom_divide) prod_diff1:
  1161   assumes "finite A" and "f a \<noteq> 0"
  1161   assumes "finite A" and "f a \<noteq> 0"
  1162   shows "setprod f (A - {a}) = (if a \<in> A then setprod f A div f a else setprod f A)"
  1162   shows "prod f (A - {a}) = (if a \<in> A then prod f A div f a else prod f A)"
  1163 proof (cases "a \<notin> A")
  1163 proof (cases "a \<notin> A")
  1164   case True
  1164   case True
  1165   then show ?thesis by simp
  1165   then show ?thesis by simp
  1166 next
  1166 next
  1167   case False
  1167   case False
  1194 lemma sum_zero_power' [simp]:
  1194 lemma sum_zero_power' [simp]:
  1195   "(\<Sum>i\<in>A. c i * 0^i / d i) = (if finite A \<and> 0 \<in> A then c 0 / d 0 else 0)"
  1195   "(\<Sum>i\<in>A. c i * 0^i / d i) = (if finite A \<and> 0 \<in> A then c 0 / d 0 else 0)"
  1196   for c :: "nat \<Rightarrow> 'a::field"
  1196   for c :: "nat \<Rightarrow> 'a::field"
  1197   using sum_zero_power [of "\<lambda>i. c i / d i" A] by auto
  1197   using sum_zero_power [of "\<lambda>i. c i / d i" A] by auto
  1198 
  1198 
  1199 lemma (in field) setprod_inversef:
  1199 lemma (in field) prod_inversef:
  1200   "finite A \<Longrightarrow> setprod (inverse \<circ> f) A = inverse (setprod f A)"
  1200   "finite A \<Longrightarrow> prod (inverse \<circ> f) A = inverse (prod f A)"
  1201   by (induct A rule: finite_induct) simp_all
  1201   by (induct A rule: finite_induct) simp_all
  1202 
  1202 
  1203 lemma (in field) setprod_dividef: "finite A \<Longrightarrow> (\<Prod>x\<in>A. f x / g x) = setprod f A / setprod g A"
  1203 lemma (in field) prod_dividef: "finite A \<Longrightarrow> (\<Prod>x\<in>A. f x / g x) = prod f A / prod g A"
  1204   using setprod_inversef [of A g] by (simp add: divide_inverse setprod.distrib)
  1204   using prod_inversef [of A g] by (simp add: divide_inverse prod.distrib)
  1205 
  1205 
  1206 lemma setprod_Un:
  1206 lemma prod_Un:
  1207   fixes f :: "'b \<Rightarrow> 'a :: field"
  1207   fixes f :: "'b \<Rightarrow> 'a :: field"
  1208   assumes "finite A" and "finite B"
  1208   assumes "finite A" and "finite B"
  1209     and "\<forall>x\<in>A \<inter> B. f x \<noteq> 0"
  1209     and "\<forall>x\<in>A \<inter> B. f x \<noteq> 0"
  1210   shows "setprod f (A \<union> B) = setprod f A * setprod f B / setprod f (A \<inter> B)"
  1210   shows "prod f (A \<union> B) = prod f A * prod f B / prod f (A \<inter> B)"
  1211 proof -
  1211 proof -
  1212   from assms have "setprod f A * setprod f B = setprod f (A \<union> B) * setprod f (A \<inter> B)"
  1212   from assms have "prod f A * prod f B = prod f (A \<union> B) * prod f (A \<inter> B)"
  1213     by (simp add: setprod.union_inter [symmetric, of A B])
  1213     by (simp add: prod.union_inter [symmetric, of A B])
  1214   with assms show ?thesis
  1214   with assms show ?thesis
  1215     by simp
  1215     by simp
  1216 qed
  1216 qed
  1217 
  1217 
  1218 lemma (in linordered_semidom) setprod_nonneg: "(\<forall>a\<in>A. 0 \<le> f a) \<Longrightarrow> 0 \<le> setprod f A"
  1218 lemma (in linordered_semidom) prod_nonneg: "(\<forall>a\<in>A. 0 \<le> f a) \<Longrightarrow> 0 \<le> prod f A"
  1219   by (induct A rule: infinite_finite_induct) simp_all
  1219   by (induct A rule: infinite_finite_induct) simp_all
  1220 
  1220 
  1221 lemma (in linordered_semidom) setprod_pos: "(\<forall>a\<in>A. 0 < f a) \<Longrightarrow> 0 < setprod f A"
  1221 lemma (in linordered_semidom) prod_pos: "(\<forall>a\<in>A. 0 < f a) \<Longrightarrow> 0 < prod f A"
  1222   by (induct A rule: infinite_finite_induct) simp_all
  1222   by (induct A rule: infinite_finite_induct) simp_all
  1223 
  1223 
  1224 lemma (in linordered_semidom) setprod_mono:
  1224 lemma (in linordered_semidom) prod_mono:
  1225   "\<forall>i\<in>A. 0 \<le> f i \<and> f i \<le> g i \<Longrightarrow> setprod f A \<le> setprod g A"
  1225   "\<forall>i\<in>A. 0 \<le> f i \<and> f i \<le> g i \<Longrightarrow> prod f A \<le> prod g A"
  1226   by (induct A rule: infinite_finite_induct) (auto intro!: setprod_nonneg mult_mono)
  1226   by (induct A rule: infinite_finite_induct) (auto intro!: prod_nonneg mult_mono)
  1227 
  1227 
  1228 lemma (in linordered_semidom) setprod_mono_strict:
  1228 lemma (in linordered_semidom) prod_mono_strict:
  1229   assumes "finite A" "\<forall>i\<in>A. 0 \<le> f i \<and> f i < g i" "A \<noteq> {}"
  1229   assumes "finite A" "\<forall>i\<in>A. 0 \<le> f i \<and> f i < g i" "A \<noteq> {}"
  1230   shows "setprod f A < setprod g A"
  1230   shows "prod f A < prod g A"
  1231   using assms
  1231   using assms
  1232 proof (induct A rule: finite_induct)
  1232 proof (induct A rule: finite_induct)
  1233   case empty
  1233   case empty
  1234   then show ?case by simp
  1234   then show ?case by simp
  1235 next
  1235 next
  1236   case insert
  1236   case insert
  1237   then show ?case by (force intro: mult_strict_mono' setprod_nonneg)
  1237   then show ?case by (force intro: mult_strict_mono' prod_nonneg)
  1238 qed
  1238 qed
  1239 
  1239 
  1240 lemma (in linordered_field) abs_setprod: "\<bar>setprod f A\<bar> = (\<Prod>x\<in>A. \<bar>f x\<bar>)"
  1240 lemma (in linordered_field) abs_prod: "\<bar>prod f A\<bar> = (\<Prod>x\<in>A. \<bar>f x\<bar>)"
  1241   by (induct A rule: infinite_finite_induct) (simp_all add: abs_mult)
  1241   by (induct A rule: infinite_finite_induct) (simp_all add: abs_mult)
  1242 
  1242 
  1243 lemma setprod_eq_1_iff [simp]: "finite A \<Longrightarrow> setprod f A = 1 \<longleftrightarrow> (\<forall>a\<in>A. f a = 1)"
  1243 lemma prod_eq_1_iff [simp]: "finite A \<Longrightarrow> prod f A = 1 \<longleftrightarrow> (\<forall>a\<in>A. f a = 1)"
  1244   for f :: "'a \<Rightarrow> nat"
  1244   for f :: "'a \<Rightarrow> nat"
  1245   by (induct A rule: finite_induct) simp_all
  1245   by (induct A rule: finite_induct) simp_all
  1246 
  1246 
  1247 lemma setprod_pos_nat_iff [simp]: "finite A \<Longrightarrow> setprod f A > 0 \<longleftrightarrow> (\<forall>a\<in>A. f a > 0)"
  1247 lemma prod_pos_nat_iff [simp]: "finite A \<Longrightarrow> prod f A > 0 \<longleftrightarrow> (\<forall>a\<in>A. f a > 0)"
  1248   for f :: "'a \<Rightarrow> nat"
  1248   for f :: "'a \<Rightarrow> nat"
  1249   using setprod_zero_iff by (simp del: neq0_conv add: zero_less_iff_neq_zero)
  1249   using prod_zero_iff by (simp del: neq0_conv add: zero_less_iff_neq_zero)
  1250 
  1250 
  1251 lemma setprod_constant: "(\<Prod>x\<in> A. y) = y ^ card A"
  1251 lemma prod_constant: "(\<Prod>x\<in> A. y) = y ^ card A"
  1252   for y :: "'a::comm_monoid_mult"
  1252   for y :: "'a::comm_monoid_mult"
  1253   by (induct A rule: infinite_finite_induct) simp_all
  1253   by (induct A rule: infinite_finite_induct) simp_all
  1254 
  1254 
  1255 lemma setprod_power_distrib: "setprod f A ^ n = setprod (\<lambda>x. (f x) ^ n) A"
  1255 lemma prod_power_distrib: "prod f A ^ n = prod (\<lambda>x. (f x) ^ n) A"
  1256   for f :: "'a \<Rightarrow> 'b::comm_semiring_1"
  1256   for f :: "'a \<Rightarrow> 'b::comm_semiring_1"
  1257   by (induct A rule: infinite_finite_induct) (auto simp add: power_mult_distrib)
  1257   by (induct A rule: infinite_finite_induct) (auto simp add: power_mult_distrib)
  1258 
  1258 
  1259 lemma power_sum: "c ^ (\<Sum>a\<in>A. f a) = (\<Prod>a\<in>A. c ^ f a)"
  1259 lemma power_sum: "c ^ (\<Sum>a\<in>A. f a) = (\<Prod>a\<in>A. c ^ f a)"
  1260   by (induct A rule: infinite_finite_induct) (simp_all add: power_add)
  1260   by (induct A rule: infinite_finite_induct) (simp_all add: power_add)
  1261 
  1261 
  1262 lemma setprod_gen_delta:
  1262 lemma prod_gen_delta:
  1263   fixes b :: "'b \<Rightarrow> 'a::comm_monoid_mult"
  1263   fixes b :: "'b \<Rightarrow> 'a::comm_monoid_mult"
  1264   assumes fin: "finite S"
  1264   assumes fin: "finite S"
  1265   shows "setprod (\<lambda>k. if k = a then b k else c) S =
  1265   shows "prod (\<lambda>k. if k = a then b k else c) S =
  1266     (if a \<in> S then b a * c ^ (card S - 1) else c ^ card S)"
  1266     (if a \<in> S then b a * c ^ (card S - 1) else c ^ card S)"
  1267 proof -
  1267 proof -
  1268   let ?f = "(\<lambda>k. if k=a then b k else c)"
  1268   let ?f = "(\<lambda>k. if k=a then b k else c)"
  1269   show ?thesis
  1269   show ?thesis
  1270   proof (cases "a \<in> S")
  1270   proof (cases "a \<in> S")
  1271     case False
  1271     case False
  1272     then have "\<forall> k\<in> S. ?f k = c" by simp
  1272     then have "\<forall> k\<in> S. ?f k = c" by simp
  1273     with False show ?thesis by (simp add: setprod_constant)
  1273     with False show ?thesis by (simp add: prod_constant)
  1274   next
  1274   next
  1275     case True
  1275     case True
  1276     let ?A = "S - {a}"
  1276     let ?A = "S - {a}"
  1277     let ?B = "{a}"
  1277     let ?B = "{a}"
  1278     from True have eq: "S = ?A \<union> ?B" by blast
  1278     from True have eq: "S = ?A \<union> ?B" by blast
  1279     have disjoint: "?A \<inter> ?B = {}" by simp
  1279     have disjoint: "?A \<inter> ?B = {}" by simp
  1280     from fin have fin': "finite ?A" "finite ?B" by auto
  1280     from fin have fin': "finite ?A" "finite ?B" by auto
  1281     have f_A0: "setprod ?f ?A = setprod (\<lambda>i. c) ?A"
  1281     have f_A0: "prod ?f ?A = prod (\<lambda>i. c) ?A"
  1282       by (rule setprod.cong) auto
  1282       by (rule prod.cong) auto
  1283     from fin True have card_A: "card ?A = card S - 1" by auto
  1283     from fin True have card_A: "card ?A = card S - 1" by auto
  1284     have f_A1: "setprod ?f ?A = c ^ card ?A"
  1284     have f_A1: "prod ?f ?A = c ^ card ?A"
  1285       unfolding f_A0 by (rule setprod_constant)
  1285       unfolding f_A0 by (rule prod_constant)
  1286     have "setprod ?f ?A * setprod ?f ?B = setprod ?f S"
  1286     have "prod ?f ?A * prod ?f ?B = prod ?f S"
  1287       using setprod.union_disjoint[OF fin' disjoint, of ?f, unfolded eq[symmetric]]
  1287       using prod.union_disjoint[OF fin' disjoint, of ?f, unfolded eq[symmetric]]
  1288       by simp
  1288       by simp
  1289     with True card_A show ?thesis
  1289     with True card_A show ?thesis
  1290       by (simp add: f_A1 field_simps cong add: setprod.cong cong del: if_weak_cong)
  1290       by (simp add: f_A1 field_simps cong add: prod.cong cong del: if_weak_cong)
  1291   qed
  1291   qed
  1292 qed
  1292 qed
  1293 
  1293 
  1294 lemma sum_image_le:
  1294 lemma sum_image_le:
  1295   fixes g :: "'a \<Rightarrow> 'b::ordered_ab_group_add"
  1295   fixes g :: "'a \<Rightarrow> 'b::ordered_ab_group_add"