| author | aspinall | 
| Fri, 01 Oct 2004 11:51:55 +0200 | |
| changeset 15220 | cc88c8ee4d2f | 
| parent 15140 | 322485b816ac | 
| child 15228 | 4d332d10fa3d | 
| permissions | -rw-r--r-- | 
| 12396 | 1 | (* Title: HOL/Finite_Set.thy | 
| 2 | ID: $Id$ | |
| 3 | Author: Tobias Nipkow, Lawrence C Paulson and Markus Wenzel | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 4 | Additions by Jeremy Avigad in Feb 2004 | 
| 12396 | 5 | *) | 
| 6 | ||
| 7 | header {* Finite sets *}
 | |
| 8 | ||
| 15131 | 9 | theory Finite_Set | 
| 15140 | 10 | imports Divides Power Inductive | 
| 15131 | 11 | begin | 
| 12396 | 12 | |
| 13 | subsection {* Collection of finite sets *}
 | |
| 14 | ||
| 15 | consts Finites :: "'a set set" | |
| 13737 | 16 | syntax | 
| 17 | finite :: "'a set => bool" | |
| 18 | translations | |
| 19 | "finite A" == "A : Finites" | |
| 12396 | 20 | |
| 21 | inductive Finites | |
| 22 | intros | |
| 23 |     emptyI [simp, intro!]: "{} : Finites"
 | |
| 24 | insertI [simp, intro!]: "A : Finites ==> insert a A : Finites" | |
| 25 | ||
| 26 | axclass finite \<subseteq> type | |
| 27 | finite: "finite UNIV" | |
| 28 | ||
| 13737 | 29 | lemma ex_new_if_finite: -- "does not depend on def of finite at all" | 
| 14661 | 30 | assumes "\<not> finite (UNIV :: 'a set)" and "finite A" | 
| 31 | shows "\<exists>a::'a. a \<notin> A" | |
| 32 | proof - | |
| 33 | from prems have "A \<noteq> UNIV" by blast | |
| 34 | thus ?thesis by blast | |
| 35 | qed | |
| 12396 | 36 | |
| 37 | lemma finite_induct [case_names empty insert, induct set: Finites]: | |
| 38 | "finite F ==> | |
| 39 |     P {} ==> (!!F x. finite F ==> x \<notin> F ==> P F ==> P (insert x F)) ==> P F"
 | |
| 40 |   -- {* Discharging @{text "x \<notin> F"} entails extra work. *}
 | |
| 41 | proof - | |
| 13421 | 42 |   assume "P {}" and
 | 
| 43 | insert: "!!F x. finite F ==> x \<notin> F ==> P F ==> P (insert x F)" | |
| 12396 | 44 | assume "finite F" | 
| 45 | thus "P F" | |
| 46 | proof induct | |
| 47 |     show "P {}" .
 | |
| 48 | fix F x assume F: "finite F" and P: "P F" | |
| 49 | show "P (insert x F)" | |
| 50 | proof cases | |
| 51 | assume "x \<in> F" | |
| 52 | hence "insert x F = F" by (rule insert_absorb) | |
| 53 | with P show ?thesis by (simp only:) | |
| 54 | next | |
| 55 | assume "x \<notin> F" | |
| 56 | from F this P show ?thesis by (rule insert) | |
| 57 | qed | |
| 58 | qed | |
| 59 | qed | |
| 60 | ||
| 61 | lemma finite_subset_induct [consumes 2, case_names empty insert]: | |
| 62 | "finite F ==> F \<subseteq> A ==> | |
| 63 |     P {} ==> (!!F a. finite F ==> a \<in> A ==> a \<notin> F ==> P F ==> P (insert a F)) ==>
 | |
| 64 | P F" | |
| 65 | proof - | |
| 13421 | 66 |   assume "P {}" and insert:
 | 
| 67 | "!!F a. finite F ==> a \<in> A ==> a \<notin> F ==> P F ==> P (insert a F)" | |
| 12396 | 68 | assume "finite F" | 
| 69 | thus "F \<subseteq> A ==> P F" | |
| 70 | proof induct | |
| 71 |     show "P {}" .
 | |
| 72 | fix F x assume "finite F" and "x \<notin> F" | |
| 73 | and P: "F \<subseteq> A ==> P F" and i: "insert x F \<subseteq> A" | |
| 74 | show "P (insert x F)" | |
| 75 | proof (rule insert) | |
| 76 | from i show "x \<in> A" by blast | |
| 77 | from i have "F \<subseteq> A" by blast | |
| 78 | with P show "P F" . | |
| 79 | qed | |
| 80 | qed | |
| 81 | qed | |
| 82 | ||
| 83 | lemma finite_UnI: "finite F ==> finite G ==> finite (F Un G)" | |
| 84 |   -- {* The union of two finite sets is finite. *}
 | |
| 85 | by (induct set: Finites) simp_all | |
| 86 | ||
| 87 | lemma finite_subset: "A \<subseteq> B ==> finite B ==> finite A" | |
| 88 |   -- {* Every subset of a finite set is finite. *}
 | |
| 89 | proof - | |
| 90 | assume "finite B" | |
| 91 | thus "!!A. A \<subseteq> B ==> finite A" | |
| 92 | proof induct | |
| 93 | case empty | |
| 94 | thus ?case by simp | |
| 95 | next | |
| 96 | case (insert F x A) | |
| 97 |     have A: "A \<subseteq> insert x F" and r: "A - {x} \<subseteq> F ==> finite (A - {x})" .
 | |
| 98 | show "finite A" | |
| 99 | proof cases | |
| 100 | assume x: "x \<in> A" | |
| 101 |       with A have "A - {x} \<subseteq> F" by (simp add: subset_insert_iff)
 | |
| 102 |       with r have "finite (A - {x})" .
 | |
| 103 |       hence "finite (insert x (A - {x}))" ..
 | |
| 104 |       also have "insert x (A - {x}) = A" by (rule insert_Diff)
 | |
| 105 | finally show ?thesis . | |
| 106 | next | |
| 107 | show "A \<subseteq> F ==> ?thesis" . | |
| 108 | assume "x \<notin> A" | |
| 109 | with A show "A \<subseteq> F" by (simp add: subset_insert_iff) | |
| 110 | qed | |
| 111 | qed | |
| 112 | qed | |
| 113 | ||
| 114 | lemma finite_Un [iff]: "finite (F Un G) = (finite F & finite G)" | |
| 115 | by (blast intro: finite_subset [of _ "X Un Y", standard] finite_UnI) | |
| 116 | ||
| 117 | lemma finite_Int [simp, intro]: "finite F | finite G ==> finite (F Int G)" | |
| 118 |   -- {* The converse obviously fails. *}
 | |
| 119 | by (blast intro: finite_subset) | |
| 120 | ||
| 121 | lemma finite_insert [simp]: "finite (insert a A) = finite A" | |
| 122 | apply (subst insert_is_Un) | |
| 14208 | 123 | apply (simp only: finite_Un, blast) | 
| 12396 | 124 | done | 
| 125 | ||
| 126 | lemma finite_empty_induct: | |
| 127 | "finite A ==> | |
| 128 |   P A ==> (!!a A. finite A ==> a:A ==> P A ==> P (A - {a})) ==> P {}"
 | |
| 129 | proof - | |
| 130 | assume "finite A" | |
| 131 |     and "P A" and "!!a A. finite A ==> a:A ==> P A ==> P (A - {a})"
 | |
| 132 | have "P (A - A)" | |
| 133 | proof - | |
| 134 | fix c b :: "'a set" | |
| 135 | presume c: "finite c" and b: "finite b" | |
| 136 |       and P1: "P b" and P2: "!!x y. finite y ==> x \<in> y ==> P y ==> P (y - {x})"
 | |
| 137 | from c show "c \<subseteq> b ==> P (b - c)" | |
| 138 | proof induct | |
| 139 | case empty | |
| 140 | from P1 show ?case by simp | |
| 141 | next | |
| 142 | case (insert F x) | |
| 143 |       have "P (b - F - {x})"
 | |
| 144 | proof (rule P2) | |
| 145 | from _ b show "finite (b - F)" by (rule finite_subset) blast | |
| 146 | from insert show "x \<in> b - F" by simp | |
| 147 | from insert show "P (b - F)" by simp | |
| 148 | qed | |
| 149 |       also have "b - F - {x} = b - insert x F" by (rule Diff_insert [symmetric])
 | |
| 150 | finally show ?case . | |
| 151 | qed | |
| 152 | next | |
| 153 | show "A \<subseteq> A" .. | |
| 154 | qed | |
| 155 |   thus "P {}" by simp
 | |
| 156 | qed | |
| 157 | ||
| 158 | lemma finite_Diff [simp]: "finite B ==> finite (B - Ba)" | |
| 159 | by (rule Diff_subset [THEN finite_subset]) | |
| 160 | ||
| 161 | lemma finite_Diff_insert [iff]: "finite (A - insert a B) = finite (A - B)" | |
| 162 | apply (subst Diff_insert) | |
| 163 | apply (case_tac "a : A - B") | |
| 164 | apply (rule finite_insert [symmetric, THEN trans]) | |
| 14208 | 165 | apply (subst insert_Diff, simp_all) | 
| 12396 | 166 | done | 
| 167 | ||
| 168 | ||
| 13825 | 169 | subsubsection {* Image and Inverse Image over Finite Sets *}
 | 
| 170 | ||
| 171 | lemma finite_imageI[simp]: "finite F ==> finite (h ` F)" | |
| 172 |   -- {* The image of a finite set is finite. *}
 | |
| 173 | by (induct set: Finites) simp_all | |
| 174 | ||
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 175 | lemma finite_surj: "finite A ==> B <= f ` A ==> finite B" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 176 | apply (frule finite_imageI) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 177 | apply (erule finite_subset, assumption) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 178 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 179 | |
| 13825 | 180 | lemma finite_range_imageI: | 
| 181 | "finite (range g) ==> finite (range (%x. f (g x)))" | |
| 14208 | 182 | apply (drule finite_imageI, simp) | 
| 13825 | 183 | done | 
| 184 | ||
| 12396 | 185 | lemma finite_imageD: "finite (f`A) ==> inj_on f A ==> finite A" | 
| 186 | proof - | |
| 187 |   have aux: "!!A. finite (A - {}) = finite A" by simp
 | |
| 188 | fix B :: "'a set" | |
| 189 | assume "finite B" | |
| 190 | thus "!!A. f`A = B ==> inj_on f A ==> finite A" | |
| 191 | apply induct | |
| 192 | apply simp | |
| 193 |     apply (subgoal_tac "EX y:A. f y = x & F = f ` (A - {y})")
 | |
| 194 | apply clarify | |
| 195 | apply (simp (no_asm_use) add: inj_on_def) | |
| 14208 | 196 | apply (blast dest!: aux [THEN iffD1], atomize) | 
| 12396 | 197 | apply (erule_tac V = "ALL A. ?PP (A)" in thin_rl) | 
| 14208 | 198 | apply (frule subsetD [OF equalityD2 insertI1], clarify) | 
| 12396 | 199 | apply (rule_tac x = xa in bexI) | 
| 200 | apply (simp_all add: inj_on_image_set_diff) | |
| 201 | done | |
| 202 | qed (rule refl) | |
| 203 | ||
| 204 | ||
| 13825 | 205 | lemma inj_vimage_singleton: "inj f ==> f-`{a} \<subseteq> {THE x. f x = a}"
 | 
| 206 |   -- {* The inverse image of a singleton under an injective function
 | |
| 207 | is included in a singleton. *} | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 208 | apply (auto simp add: inj_on_def) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 209 | apply (blast intro: the_equality [symmetric]) | 
| 13825 | 210 | done | 
| 211 | ||
| 212 | lemma finite_vimageI: "[|finite F; inj h|] ==> finite (h -` F)" | |
| 213 |   -- {* The inverse image of a finite set under an injective function
 | |
| 214 | is finite. *} | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 215 | apply (induct set: Finites, simp_all) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 216 | apply (subst vimage_insert) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 217 | apply (simp add: finite_Un finite_subset [OF inj_vimage_singleton]) | 
| 13825 | 218 | done | 
| 219 | ||
| 220 | ||
| 12396 | 221 | subsubsection {* The finite UNION of finite sets *}
 | 
| 222 | ||
| 223 | lemma finite_UN_I: "finite A ==> (!!a. a:A ==> finite (B a)) ==> finite (UN a:A. B a)" | |
| 224 | by (induct set: Finites) simp_all | |
| 225 | ||
| 226 | text {*
 | |
| 227 | Strengthen RHS to | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 228 |   @{prop "((ALL x:A. finite (B x)) & finite {x. x:A & B x \<noteq> {}})"}?
 | 
| 12396 | 229 | |
| 230 | We'd need to prove | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 231 |   @{prop "finite C ==> ALL A B. (UNION A B) <= C --> finite {x. x:A & B x \<noteq> {}}"}
 | 
| 12396 | 232 | by induction. *} | 
| 233 | ||
| 234 | lemma finite_UN [simp]: "finite A ==> finite (UNION A B) = (ALL x:A. finite (B x))" | |
| 235 | by (blast intro: finite_UN_I finite_subset) | |
| 236 | ||
| 237 | ||
| 238 | subsubsection {* Sigma of finite sets *}
 | |
| 239 | ||
| 240 | lemma finite_SigmaI [simp]: | |
| 241 | "finite A ==> (!!a. a:A ==> finite (B a)) ==> finite (SIGMA a:A. B a)" | |
| 242 | by (unfold Sigma_def) (blast intro!: finite_UN_I) | |
| 243 | ||
| 244 | lemma finite_Prod_UNIV: | |
| 245 |     "finite (UNIV::'a set) ==> finite (UNIV::'b set) ==> finite (UNIV::('a * 'b) set)"
 | |
| 246 |   apply (subgoal_tac "(UNIV:: ('a * 'b) set) = Sigma UNIV (%x. UNIV)")
 | |
| 247 | apply (erule ssubst) | |
| 14208 | 248 | apply (erule finite_SigmaI, auto) | 
| 12396 | 249 | done | 
| 250 | ||
| 251 | instance unit :: finite | |
| 252 | proof | |
| 253 |   have "finite {()}" by simp
 | |
| 254 |   also have "{()} = UNIV" by auto
 | |
| 255 | finally show "finite (UNIV :: unit set)" . | |
| 256 | qed | |
| 257 | ||
| 258 | instance * :: (finite, finite) finite | |
| 259 | proof | |
| 260 |   show "finite (UNIV :: ('a \<times> 'b) set)"
 | |
| 261 | proof (rule finite_Prod_UNIV) | |
| 262 | show "finite (UNIV :: 'a set)" by (rule finite) | |
| 263 | show "finite (UNIV :: 'b set)" by (rule finite) | |
| 264 | qed | |
| 265 | qed | |
| 266 | ||
| 267 | ||
| 268 | subsubsection {* The powerset of a finite set *}
 | |
| 269 | ||
| 270 | lemma finite_Pow_iff [iff]: "finite (Pow A) = finite A" | |
| 271 | proof | |
| 272 | assume "finite (Pow A)" | |
| 273 |   with _ have "finite ((%x. {x}) ` A)" by (rule finite_subset) blast
 | |
| 274 | thus "finite A" by (rule finite_imageD [unfolded inj_on_def]) simp | |
| 275 | next | |
| 276 | assume "finite A" | |
| 277 | thus "finite (Pow A)" | |
| 278 | by induct (simp_all add: finite_UnI finite_imageI Pow_insert) | |
| 279 | qed | |
| 280 | ||
| 281 | lemma finite_converse [iff]: "finite (r^-1) = finite r" | |
| 282 | apply (subgoal_tac "r^-1 = (%(x,y). (y,x))`r") | |
| 283 | apply simp | |
| 284 | apply (rule iffI) | |
| 285 | apply (erule finite_imageD [unfolded inj_on_def]) | |
| 286 | apply (simp split add: split_split) | |
| 287 | apply (erule finite_imageI) | |
| 14208 | 288 | apply (simp add: converse_def image_def, auto) | 
| 12396 | 289 | apply (rule bexI) | 
| 290 | prefer 2 apply assumption | |
| 291 | apply simp | |
| 292 | done | |
| 293 | ||
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 294 | |
| 12396 | 295 | subsubsection {* Finiteness of transitive closure *}
 | 
| 296 | ||
| 297 | text {* (Thanks to Sidi Ehmety) *}
 | |
| 298 | ||
| 299 | lemma finite_Field: "finite r ==> finite (Field r)" | |
| 300 |   -- {* A finite relation has a finite field (@{text "= domain \<union> range"}. *}
 | |
| 301 | apply (induct set: Finites) | |
| 302 | apply (auto simp add: Field_def Domain_insert Range_insert) | |
| 303 | done | |
| 304 | ||
| 305 | lemma trancl_subset_Field2: "r^+ <= Field r \<times> Field r" | |
| 306 | apply clarify | |
| 307 | apply (erule trancl_induct) | |
| 308 | apply (auto simp add: Field_def) | |
| 309 | done | |
| 310 | ||
| 311 | lemma finite_trancl: "finite (r^+) = finite r" | |
| 312 | apply auto | |
| 313 | prefer 2 | |
| 314 | apply (rule trancl_subset_Field2 [THEN finite_subset]) | |
| 315 | apply (rule finite_SigmaI) | |
| 316 | prefer 3 | |
| 13704 
854501b1e957
Transitive closure is now defined inductively as well.
 berghofe parents: 
13595diff
changeset | 317 | apply (blast intro: r_into_trancl' finite_subset) | 
| 12396 | 318 | apply (auto simp add: finite_Field) | 
| 319 | done | |
| 320 | ||
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 321 | lemma finite_cartesian_product: "[| finite A; finite B |] ==> | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 322 | finite (A <*> B)" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 323 | by (rule finite_SigmaI) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 324 | |
| 12396 | 325 | |
| 326 | subsection {* Finite cardinality *}
 | |
| 327 | ||
| 328 | text {*
 | |
| 329 |   This definition, although traditional, is ugly to work with: @{text
 | |
| 330 |   "card A == LEAST n. EX f. A = {f i | i. i < n}"}.  Therefore we have
 | |
| 331 | switched to an inductive one: | |
| 332 | *} | |
| 333 | ||
| 334 | consts cardR :: "('a set \<times> nat) set"
 | |
| 335 | ||
| 336 | inductive cardR | |
| 337 | intros | |
| 338 |     EmptyI: "({}, 0) : cardR"
 | |
| 339 | InsertI: "(A, n) : cardR ==> a \<notin> A ==> (insert a A, Suc n) : cardR" | |
| 340 | ||
| 341 | constdefs | |
| 342 | card :: "'a set => nat" | |
| 343 | "card A == THE n. (A, n) : cardR" | |
| 344 | ||
| 345 | inductive_cases cardR_emptyE: "({}, n) : cardR"
 | |
| 346 | inductive_cases cardR_insertE: "(insert a A,n) : cardR" | |
| 347 | ||
| 348 | lemma cardR_SucD: "(A, n) : cardR ==> a : A --> (EX m. n = Suc m)" | |
| 349 | by (induct set: cardR) simp_all | |
| 350 | ||
| 351 | lemma cardR_determ_aux1: | |
| 352 |     "(A, m): cardR ==> (!!n a. m = Suc n ==> a:A ==> (A - {a}, n) : cardR)"
 | |
| 14208 | 353 | apply (induct set: cardR, auto) | 
| 354 | apply (simp add: insert_Diff_if, auto) | |
| 12396 | 355 | apply (drule cardR_SucD) | 
| 356 | apply (blast intro!: cardR.intros) | |
| 357 | done | |
| 358 | ||
| 359 | lemma cardR_determ_aux2: "(insert a A, Suc m) : cardR ==> a \<notin> A ==> (A, m) : cardR" | |
| 360 | by (drule cardR_determ_aux1) auto | |
| 361 | ||
| 362 | lemma cardR_determ: "(A, m): cardR ==> (!!n. (A, n) : cardR ==> n = m)" | |
| 363 | apply (induct set: cardR) | |
| 364 | apply (safe elim!: cardR_emptyE cardR_insertE) | |
| 365 | apply (rename_tac B b m) | |
| 366 | apply (case_tac "a = b") | |
| 367 | apply (subgoal_tac "A = B") | |
| 14208 | 368 | prefer 2 apply (blast elim: equalityE, blast) | 
| 12396 | 369 | apply (subgoal_tac "EX C. A = insert b C & B = insert a C") | 
| 370 | prefer 2 | |
| 371 | apply (rule_tac x = "A Int B" in exI) | |
| 372 | apply (blast elim: equalityE) | |
| 373 | apply (frule_tac A = B in cardR_SucD) | |
| 374 | apply (blast intro!: cardR.intros dest!: cardR_determ_aux2) | |
| 375 | done | |
| 376 | ||
| 377 | lemma cardR_imp_finite: "(A, n) : cardR ==> finite A" | |
| 378 | by (induct set: cardR) simp_all | |
| 379 | ||
| 380 | lemma finite_imp_cardR: "finite A ==> EX n. (A, n) : cardR" | |
| 381 | by (induct set: Finites) (auto intro!: cardR.intros) | |
| 382 | ||
| 383 | lemma card_equality: "(A,n) : cardR ==> card A = n" | |
| 384 | by (unfold card_def) (blast intro: cardR_determ) | |
| 385 | ||
| 386 | lemma card_empty [simp]: "card {} = 0"
 | |
| 387 | by (unfold card_def) (blast intro!: cardR.intros elim!: cardR_emptyE) | |
| 388 | ||
| 389 | lemma card_insert_disjoint [simp]: | |
| 390 | "finite A ==> x \<notin> A ==> card (insert x A) = Suc(card A)" | |
| 391 | proof - | |
| 392 | assume x: "x \<notin> A" | |
| 393 | hence aux: "!!n. ((insert x A, n) : cardR) = (EX m. (A, m) : cardR & n = Suc m)" | |
| 394 | apply (auto intro!: cardR.intros) | |
| 395 | apply (rule_tac A1 = A in finite_imp_cardR [THEN exE]) | |
| 396 | apply (force dest: cardR_imp_finite) | |
| 397 | apply (blast intro!: cardR.intros intro: cardR_determ) | |
| 398 | done | |
| 399 | assume "finite A" | |
| 400 | thus ?thesis | |
| 401 | apply (simp add: card_def aux) | |
| 402 | apply (rule the_equality) | |
| 403 | apply (auto intro: finite_imp_cardR | |
| 404 | cong: conj_cong simp: card_def [symmetric] card_equality) | |
| 405 | done | |
| 406 | qed | |
| 407 | ||
| 408 | lemma card_0_eq [simp]: "finite A ==> (card A = 0) = (A = {})"
 | |
| 409 | apply auto | |
| 14208 | 410 | apply (drule_tac a = x in mk_disjoint_insert, clarify) | 
| 411 | apply (rotate_tac -1, auto) | |
| 12396 | 412 | done | 
| 413 | ||
| 414 | lemma card_insert_if: | |
| 415 | "finite A ==> card (insert x A) = (if x:A then card A else Suc(card(A)))" | |
| 416 | by (simp add: insert_absorb) | |
| 417 | ||
| 418 | lemma card_Suc_Diff1: "finite A ==> x: A ==> Suc (card (A - {x})) = card A"
 | |
| 14302 | 419 | apply(rule_tac t = A in insert_Diff [THEN subst], assumption) | 
| 420 | apply(simp del:insert_Diff_single) | |
| 421 | done | |
| 12396 | 422 | |
| 423 | lemma card_Diff_singleton: | |
| 424 |     "finite A ==> x: A ==> card (A - {x}) = card A - 1"
 | |
| 425 | by (simp add: card_Suc_Diff1 [symmetric]) | |
| 426 | ||
| 427 | lemma card_Diff_singleton_if: | |
| 428 |     "finite A ==> card (A-{x}) = (if x : A then card A - 1 else card A)"
 | |
| 429 | by (simp add: card_Diff_singleton) | |
| 430 | ||
| 431 | lemma card_insert: "finite A ==> card (insert x A) = Suc (card (A - {x}))"
 | |
| 432 | by (simp add: card_insert_if card_Suc_Diff1) | |
| 433 | ||
| 434 | lemma card_insert_le: "finite A ==> card A <= card (insert x A)" | |
| 435 | by (simp add: card_insert_if) | |
| 436 | ||
| 437 | lemma card_seteq: "finite B ==> (!!A. A <= B ==> card B <= card A ==> A = B)" | |
| 14208 | 438 | apply (induct set: Finites, simp, clarify) | 
| 12396 | 439 |   apply (subgoal_tac "finite A & A - {x} <= F")
 | 
| 14208 | 440 | prefer 2 apply (blast intro: finite_subset, atomize) | 
| 12396 | 441 |   apply (drule_tac x = "A - {x}" in spec)
 | 
| 442 | apply (simp add: card_Diff_singleton_if split add: split_if_asm) | |
| 14208 | 443 | apply (case_tac "card A", auto) | 
| 12396 | 444 | done | 
| 445 | ||
| 446 | lemma psubset_card_mono: "finite B ==> A < B ==> card A < card B" | |
| 447 | apply (simp add: psubset_def linorder_not_le [symmetric]) | |
| 448 | apply (blast dest: card_seteq) | |
| 449 | done | |
| 450 | ||
| 451 | lemma card_mono: "finite B ==> A <= B ==> card A <= card B" | |
| 14208 | 452 | apply (case_tac "A = B", simp) | 
| 12396 | 453 | apply (simp add: linorder_not_less [symmetric]) | 
| 454 | apply (blast dest: card_seteq intro: order_less_imp_le) | |
| 455 | done | |
| 456 | ||
| 457 | lemma card_Un_Int: "finite A ==> finite B | |
| 458 | ==> card A + card B = card (A Un B) + card (A Int B)" | |
| 14208 | 459 | apply (induct set: Finites, simp) | 
| 12396 | 460 | apply (simp add: insert_absorb Int_insert_left) | 
| 461 | done | |
| 462 | ||
| 463 | lemma card_Un_disjoint: "finite A ==> finite B | |
| 464 |     ==> A Int B = {} ==> card (A Un B) = card A + card B"
 | |
| 465 | by (simp add: card_Un_Int) | |
| 466 | ||
| 467 | lemma card_Diff_subset: | |
| 468 | "finite A ==> B <= A ==> card A - card B = card (A - B)" | |
| 469 | apply (subgoal_tac "(A - B) Un B = A") | |
| 470 | prefer 2 apply blast | |
| 14331 | 471 | apply (rule nat_add_right_cancel [THEN iffD1]) | 
| 12396 | 472 | apply (rule card_Un_disjoint [THEN subst]) | 
| 473 | apply (erule_tac [4] ssubst) | |
| 474 | prefer 3 apply blast | |
| 475 | apply (simp_all add: add_commute not_less_iff_le | |
| 476 | add_diff_inverse card_mono finite_subset) | |
| 477 | done | |
| 478 | ||
| 479 | lemma card_Diff1_less: "finite A ==> x: A ==> card (A - {x}) < card A"
 | |
| 480 | apply (rule Suc_less_SucD) | |
| 481 | apply (simp add: card_Suc_Diff1) | |
| 482 | done | |
| 483 | ||
| 484 | lemma card_Diff2_less: | |
| 485 |     "finite A ==> x: A ==> y: A ==> card (A - {x} - {y}) < card A"
 | |
| 486 | apply (case_tac "x = y") | |
| 487 | apply (simp add: card_Diff1_less) | |
| 488 | apply (rule less_trans) | |
| 489 | prefer 2 apply (auto intro!: card_Diff1_less) | |
| 490 | done | |
| 491 | ||
| 492 | lemma card_Diff1_le: "finite A ==> card (A - {x}) <= card A"
 | |
| 493 | apply (case_tac "x : A") | |
| 494 | apply (simp_all add: card_Diff1_less less_imp_le) | |
| 495 | done | |
| 496 | ||
| 497 | lemma card_psubset: "finite B ==> A \<subseteq> B ==> card A < card B ==> A < B" | |
| 14208 | 498 | by (erule psubsetI, blast) | 
| 12396 | 499 | |
| 14889 | 500 | lemma insert_partition: | 
| 501 |      "[| x \<notin> F; \<forall>c1\<in>insert x F. \<forall>c2 \<in> insert x F. c1 \<noteq> c2 --> c1 \<inter> c2 = {}|] 
 | |
| 502 |       ==> x \<inter> \<Union> F = {}"
 | |
| 503 | by auto | |
| 504 | ||
| 505 | (* main cardinality theorem *) | |
| 506 | lemma card_partition [rule_format]: | |
| 507 | "finite C ==> | |
| 508 | finite (\<Union> C) --> | |
| 509 | (\<forall>c\<in>C. card c = k) --> | |
| 510 |         (\<forall>c1 \<in> C. \<forall>c2 \<in> C. c1 \<noteq> c2 --> c1 \<inter> c2 = {}) -->  
 | |
| 511 | k * card(C) = card (\<Union> C)" | |
| 512 | apply (erule finite_induct, simp) | |
| 513 | apply (simp add: card_insert_disjoint card_Un_disjoint insert_partition | |
| 514 | finite_subset [of _ "\<Union> (insert x F)"]) | |
| 515 | done | |
| 516 | ||
| 12396 | 517 | |
| 518 | subsubsection {* Cardinality of image *}
 | |
| 519 | ||
| 520 | lemma card_image_le: "finite A ==> card (f ` A) <= card A" | |
| 14208 | 521 | apply (induct set: Finites, simp) | 
| 12396 | 522 | apply (simp add: le_SucI finite_imageI card_insert_if) | 
| 523 | done | |
| 524 | ||
| 525 | lemma card_image: "finite A ==> inj_on f A ==> card (f ` A) = card A" | |
| 15111 | 526 | by (induct set: Finites, simp_all) | 
| 12396 | 527 | |
| 528 | lemma endo_inj_surj: "finite A ==> f ` A \<subseteq> A ==> inj_on f A ==> f ` A = A" | |
| 529 | by (simp add: card_seteq card_image) | |
| 530 | ||
| 15111 | 531 | lemma eq_card_imp_inj_on: | 
| 532 | "[| finite A; card(f ` A) = card A |] ==> inj_on f A" | |
| 533 | apply(induct rule:finite_induct) | |
| 534 | apply simp | |
| 535 | apply(frule card_image_le[where f = f]) | |
| 536 | apply(simp add:card_insert_if split:if_splits) | |
| 537 | done | |
| 538 | ||
| 539 | lemma inj_on_iff_eq_card: | |
| 540 | "finite A ==> inj_on f A = (card(f ` A) = card A)" | |
| 541 | by(blast intro: card_image eq_card_imp_inj_on) | |
| 542 | ||
| 12396 | 543 | |
| 544 | subsubsection {* Cardinality of the Powerset *}
 | |
| 545 | ||
| 546 | lemma card_Pow: "finite A ==> card (Pow A) = Suc (Suc 0) ^ card A" (* FIXME numeral 2 (!?) *) | |
| 547 | apply (induct set: Finites) | |
| 548 | apply (simp_all add: Pow_insert) | |
| 14208 | 549 | apply (subst card_Un_disjoint, blast) | 
| 550 | apply (blast intro: finite_imageI, blast) | |
| 12396 | 551 | apply (subgoal_tac "inj_on (insert x) (Pow F)") | 
| 552 | apply (simp add: card_image Pow_insert) | |
| 553 | apply (unfold inj_on_def) | |
| 554 | apply (blast elim!: equalityE) | |
| 555 | done | |
| 556 | ||
| 557 | text {*
 | |
| 558 | \medskip Relates to equivalence classes. Based on a theorem of | |
| 559 |   F. Kammüller's.  The @{prop "finite C"} premise is redundant.
 | |
| 560 | *} | |
| 561 | ||
| 562 | lemma dvd_partition: | |
| 563 | "finite C ==> finite (Union C) ==> | |
| 564 | ALL c : C. k dvd card c ==> | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 565 |     (ALL c1: C. ALL c2: C. c1 \<noteq> c2 --> c1 Int c2 = {}) ==>
 | 
| 12396 | 566 | k dvd card (Union C)" | 
| 14208 | 567 | apply (induct set: Finites, simp_all, clarify) | 
| 12396 | 568 | apply (subst card_Un_disjoint) | 
| 569 | apply (auto simp add: dvd_add disjoint_eq_subset_Compl) | |
| 570 | done | |
| 571 | ||
| 572 | ||
| 573 | subsection {* A fold functional for finite sets *}
 | |
| 574 | ||
| 575 | text {*
 | |
| 576 |   For @{text n} non-negative we have @{text "fold f e {x1, ..., xn} =
 | |
| 577 |   f x1 (... (f xn e))"} where @{text f} is at least left-commutative.
 | |
| 578 | *} | |
| 579 | ||
| 580 | consts | |
| 581 |   foldSet :: "('b => 'a => 'a) => 'a => ('b set \<times> 'a) set"
 | |
| 582 | ||
| 583 | inductive "foldSet f e" | |
| 584 | intros | |
| 585 |     emptyI [intro]: "({}, e) : foldSet f e"
 | |
| 586 | insertI [intro]: "x \<notin> A ==> (A, y) : foldSet f e ==> (insert x A, f x y) : foldSet f e" | |
| 587 | ||
| 588 | inductive_cases empty_foldSetE [elim!]: "({}, x) : foldSet f e"
 | |
| 589 | ||
| 590 | constdefs | |
| 591 |   fold :: "('b => 'a => 'a) => 'a => 'b set => 'a"
 | |
| 592 | "fold f e A == THE x. (A, x) : foldSet f e" | |
| 593 | ||
| 594 | lemma Diff1_foldSet: "(A - {x}, y) : foldSet f e ==> x: A ==> (A, f x y) : foldSet f e"
 | |
| 14208 | 595 | by (erule insert_Diff [THEN subst], rule foldSet.intros, auto) | 
| 12396 | 596 | |
| 597 | lemma foldSet_imp_finite [simp]: "(A, x) : foldSet f e ==> finite A" | |
| 598 | by (induct set: foldSet) auto | |
| 599 | ||
| 600 | lemma finite_imp_foldSet: "finite A ==> EX x. (A, x) : foldSet f e" | |
| 601 | by (induct set: Finites) auto | |
| 602 | ||
| 603 | ||
| 604 | subsubsection {* Left-commutative operations *}
 | |
| 605 | ||
| 606 | locale LC = | |
| 607 | fixes f :: "'b => 'a => 'a" (infixl "\<cdot>" 70) | |
| 608 | assumes left_commute: "x \<cdot> (y \<cdot> z) = y \<cdot> (x \<cdot> z)" | |
| 609 | ||
| 610 | lemma (in LC) foldSet_determ_aux: | |
| 611 | "ALL A x. card A < n --> (A, x) : foldSet f e --> | |
| 612 | (ALL y. (A, y) : foldSet f e --> y = x)" | |
| 613 | apply (induct n) | |
| 614 | apply (auto simp add: less_Suc_eq) | |
| 14208 | 615 | apply (erule foldSet.cases, blast) | 
| 616 | apply (erule foldSet.cases, blast, clarify) | |
| 12396 | 617 |   txt {* force simplification of @{text "card A < card (insert ...)"}. *}
 | 
| 618 | apply (erule rev_mp) | |
| 619 | apply (simp add: less_Suc_eq_le) | |
| 620 | apply (rule impI) | |
| 621 | apply (rename_tac Aa xa ya Ab xb yb, case_tac "xa = xb") | |
| 622 | apply (subgoal_tac "Aa = Ab") | |
| 14208 | 623 | prefer 2 apply (blast elim!: equalityE, blast) | 
| 12396 | 624 |   txt {* case @{prop "xa \<notin> xb"}. *}
 | 
| 625 |   apply (subgoal_tac "Aa - {xb} = Ab - {xa} & xb : Aa & xa : Ab")
 | |
| 14208 | 626 | prefer 2 apply (blast elim!: equalityE, clarify) | 
| 12396 | 627 |   apply (subgoal_tac "Aa = insert xb Ab - {xa}")
 | 
| 628 | prefer 2 apply blast | |
| 629 | apply (subgoal_tac "card Aa <= card Ab") | |
| 630 | prefer 2 | |
| 631 | apply (rule Suc_le_mono [THEN subst]) | |
| 632 | apply (simp add: card_Suc_Diff1) | |
| 633 |   apply (rule_tac A1 = "Aa - {xb}" and f1 = f in finite_imp_foldSet [THEN exE])
 | |
| 634 | apply (blast intro: foldSet_imp_finite finite_Diff) | |
| 635 | apply (frule (1) Diff1_foldSet) | |
| 636 | apply (subgoal_tac "ya = f xb x") | |
| 637 | prefer 2 apply (blast del: equalityCE) | |
| 638 |   apply (subgoal_tac "(Ab - {xa}, x) : foldSet f e")
 | |
| 639 | prefer 2 apply simp | |
| 640 | apply (subgoal_tac "yb = f xa x") | |
| 641 | prefer 2 apply (blast del: equalityCE dest: Diff1_foldSet) | |
| 642 | apply (simp (no_asm_simp) add: left_commute) | |
| 643 | done | |
| 644 | ||
| 645 | lemma (in LC) foldSet_determ: "(A, x) : foldSet f e ==> (A, y) : foldSet f e ==> y = x" | |
| 646 | by (blast intro: foldSet_determ_aux [rule_format]) | |
| 647 | ||
| 648 | lemma (in LC) fold_equality: "(A, y) : foldSet f e ==> fold f e A = y" | |
| 649 | by (unfold fold_def) (blast intro: foldSet_determ) | |
| 650 | ||
| 651 | lemma fold_empty [simp]: "fold f e {} = e"
 | |
| 652 | by (unfold fold_def) blast | |
| 653 | ||
| 654 | lemma (in LC) fold_insert_aux: "x \<notin> A ==> | |
| 655 | ((insert x A, v) : foldSet f e) = | |
| 656 | (EX y. (A, y) : foldSet f e & v = f x y)" | |
| 657 | apply auto | |
| 658 | apply (rule_tac A1 = A and f1 = f in finite_imp_foldSet [THEN exE]) | |
| 659 | apply (fastsimp dest: foldSet_imp_finite) | |
| 660 | apply (blast intro: foldSet_determ) | |
| 661 | done | |
| 662 | ||
| 663 | lemma (in LC) fold_insert: | |
| 664 | "finite A ==> x \<notin> A ==> fold f e (insert x A) = f x (fold f e A)" | |
| 665 | apply (unfold fold_def) | |
| 666 | apply (simp add: fold_insert_aux) | |
| 667 | apply (rule the_equality) | |
| 668 | apply (auto intro: finite_imp_foldSet | |
| 669 | cong add: conj_cong simp add: fold_def [symmetric] fold_equality) | |
| 670 | done | |
| 671 | ||
| 672 | lemma (in LC) fold_commute: "finite A ==> (!!e. f x (fold f e A) = fold f (f x e) A)" | |
| 14208 | 673 | apply (induct set: Finites, simp) | 
| 12396 | 674 | apply (simp add: left_commute fold_insert) | 
| 675 | done | |
| 676 | ||
| 677 | lemma (in LC) fold_nest_Un_Int: | |
| 678 | "finite A ==> finite B | |
| 679 | ==> fold f (fold f e B) A = fold f (fold f e (A Int B)) (A Un B)" | |
| 14208 | 680 | apply (induct set: Finites, simp) | 
| 12396 | 681 | apply (simp add: fold_insert fold_commute Int_insert_left insert_absorb) | 
| 682 | done | |
| 683 | ||
| 684 | lemma (in LC) fold_nest_Un_disjoint: | |
| 685 |   "finite A ==> finite B ==> A Int B = {}
 | |
| 686 | ==> fold f e (A Un B) = fold f (fold f e B) A" | |
| 687 | by (simp add: fold_nest_Un_Int) | |
| 688 | ||
| 689 | declare foldSet_imp_finite [simp del] | |
| 690 | empty_foldSetE [rule del] foldSet.intros [rule del] | |
| 691 |   -- {* Delete rules to do with @{text foldSet} relation. *}
 | |
| 692 | ||
| 693 | ||
| 694 | ||
| 695 | subsubsection {* Commutative monoids *}
 | |
| 696 | ||
| 697 | text {*
 | |
| 698 |   We enter a more restrictive context, with @{text "f :: 'a => 'a => 'a"}
 | |
| 699 |   instead of @{text "'b => 'a => 'a"}.
 | |
| 700 | *} | |
| 701 | ||
| 702 | locale ACe = | |
| 703 | fixes f :: "'a => 'a => 'a" (infixl "\<cdot>" 70) | |
| 704 | and e :: 'a | |
| 705 | assumes ident [simp]: "x \<cdot> e = x" | |
| 706 | and commute: "x \<cdot> y = y \<cdot> x" | |
| 707 | and assoc: "(x \<cdot> y) \<cdot> z = x \<cdot> (y \<cdot> z)" | |
| 708 | ||
| 709 | lemma (in ACe) left_commute: "x \<cdot> (y \<cdot> z) = y \<cdot> (x \<cdot> z)" | |
| 710 | proof - | |
| 711 | have "x \<cdot> (y \<cdot> z) = (y \<cdot> z) \<cdot> x" by (simp only: commute) | |
| 712 | also have "... = y \<cdot> (z \<cdot> x)" by (simp only: assoc) | |
| 713 | also have "z \<cdot> x = x \<cdot> z" by (simp only: commute) | |
| 714 | finally show ?thesis . | |
| 715 | qed | |
| 716 | ||
| 12718 | 717 | lemmas (in ACe) AC = assoc commute left_commute | 
| 12396 | 718 | |
| 12693 | 719 | lemma (in ACe) left_ident [simp]: "e \<cdot> x = x" | 
| 12396 | 720 | proof - | 
| 721 | have "x \<cdot> e = x" by (rule ident) | |
| 722 | thus ?thesis by (subst commute) | |
| 723 | qed | |
| 724 | ||
| 725 | lemma (in ACe) fold_Un_Int: | |
| 726 | "finite A ==> finite B ==> | |
| 727 | fold f e A \<cdot> fold f e B = fold f e (A Un B) \<cdot> fold f e (A Int B)" | |
| 14208 | 728 | apply (induct set: Finites, simp) | 
| 13400 | 729 | apply (simp add: AC insert_absorb Int_insert_left | 
| 13421 | 730 | LC.fold_insert [OF LC.intro]) | 
| 12396 | 731 | done | 
| 732 | ||
| 733 | lemma (in ACe) fold_Un_disjoint: | |
| 734 |   "finite A ==> finite B ==> A Int B = {} ==>
 | |
| 735 | fold f e (A Un B) = fold f e A \<cdot> fold f e B" | |
| 736 | by (simp add: fold_Un_Int) | |
| 737 | ||
| 738 | lemma (in ACe) fold_Un_disjoint2: | |
| 739 |   "finite A ==> finite B ==> A Int B = {} ==>
 | |
| 740 | fold (f o g) e (A Un B) = fold (f o g) e A \<cdot> fold (f o g) e B" | |
| 741 | proof - | |
| 742 | assume b: "finite B" | |
| 743 | assume "finite A" | |
| 744 |   thus "A Int B = {} ==>
 | |
| 745 | fold (f o g) e (A Un B) = fold (f o g) e A \<cdot> fold (f o g) e B" | |
| 746 | proof induct | |
| 747 | case empty | |
| 748 | thus ?case by simp | |
| 749 | next | |
| 750 | case (insert F x) | |
| 13571 | 751 | have "fold (f o g) e (insert x F \<union> B) = fold (f o g) e (insert x (F \<union> B))" | 
| 12396 | 752 | by simp | 
| 13571 | 753 | also have "... = (f o g) x (fold (f o g) e (F \<union> B))" | 
| 13400 | 754 | by (rule LC.fold_insert [OF LC.intro]) | 
| 13421 | 755 | (insert b insert, auto simp add: left_commute) | 
| 13571 | 756 | also from insert have "fold (f o g) e (F \<union> B) = | 
| 757 | fold (f o g) e F \<cdot> fold (f o g) e B" by blast | |
| 758 | also have "(f o g) x ... = (f o g) x (fold (f o g) e F) \<cdot> fold (f o g) e B" | |
| 12396 | 759 | by (simp add: AC) | 
| 13571 | 760 | also have "(f o g) x (fold (f o g) e F) = fold (f o g) e (insert x F)" | 
| 13400 | 761 | by (rule LC.fold_insert [OF LC.intro, symmetric]) (insert b insert, | 
| 14661 | 762 | auto simp add: left_commute) | 
| 12396 | 763 | finally show ?case . | 
| 764 | qed | |
| 765 | qed | |
| 766 | ||
| 767 | ||
| 768 | subsection {* Generalized summation over a set *}
 | |
| 769 | ||
| 770 | constdefs | |
| 14738 | 771 |   setsum :: "('a => 'b) => 'a set => 'b::comm_monoid_add"
 | 
| 12396 | 772 | "setsum f A == if finite A then fold (op + o f) 0 A else 0" | 
| 773 | ||
| 15042 | 774 | text{* Now: lot's of fancy syntax. First, @{term "setsum (%x. e) A"} is
 | 
| 775 | written @{text"\<Sum>x\<in>A. e"}. *}
 | |
| 776 | ||
| 12396 | 777 | syntax | 
| 15074 | 778 |   "_setsum" :: "idt => 'a set => 'b => 'b::comm_monoid_add"    ("(3SUM _:_. _)" [0, 51, 10] 10)
 | 
| 12396 | 779 | syntax (xsymbols) | 
| 14738 | 780 |   "_setsum" :: "idt => 'a set => 'b => 'b::comm_monoid_add"    ("(3\<Sum>_\<in>_. _)" [0, 51, 10] 10)
 | 
| 14565 | 781 | syntax (HTML output) | 
| 14738 | 782 |   "_setsum" :: "idt => 'a set => 'b => 'b::comm_monoid_add"    ("(3\<Sum>_\<in>_. _)" [0, 51, 10] 10)
 | 
| 15074 | 783 | |
| 784 | translations -- {* Beware of argument permutation! *}
 | |
| 785 | "SUM i:A. b" == "setsum (%i. b) A" | |
| 786 | "\<Sum>i\<in>A. b" == "setsum (%i. b) A" | |
| 12396 | 787 | |
| 15042 | 788 | text{* Instead of @{term"\<Sum>x\<in>{x. P}. e"} we introduce the shorter
 | 
| 789 |  @{text"\<Sum>x|P. e"}. *}
 | |
| 790 | ||
| 791 | syntax | |
| 15074 | 792 |   "_qsetsum" :: "idt \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a" ("(3SUM _ |/ _./ _)" [0,0,10] 10)
 | 
| 15042 | 793 | syntax (xsymbols) | 
| 794 |   "_qsetsum" :: "idt \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a" ("(3\<Sum>_ | (_)./ _)" [0,0,10] 10)
 | |
| 795 | syntax (HTML output) | |
| 796 |   "_qsetsum" :: "idt \<Rightarrow> bool \<Rightarrow> 'a \<Rightarrow> 'a" ("(3\<Sum>_ | (_)./ _)" [0,0,10] 10)
 | |
| 797 | ||
| 15074 | 798 | translations | 
| 799 |   "SUM x|P. t" => "setsum (%x. t) {x. P}"
 | |
| 800 |   "\<Sum>x|P. t" => "setsum (%x. t) {x. P}"
 | |
| 15042 | 801 | |
| 802 | print_translation {*
 | |
| 803 | let | |
| 804 |   fun setsum_tr' [Abs(x,Tx,t), Const ("Collect",_) $ Abs(y,Ty,P)] = 
 | |
| 805 | (if x<>y then raise Match | |
| 806 | else let val x' = Syntax.mark_bound x | |
| 807 | val t' = subst_bound(x',t) | |
| 808 | val P' = subst_bound(x',P) | |
| 809 | in Syntax.const "_qsetsum" $ Syntax.mark_bound x $ P' $ t' end) | |
| 810 | in | |
| 811 | [("setsum", setsum_tr')]
 | |
| 812 | end | |
| 813 | *} | |
| 814 | ||
| 15047 | 815 | text{* As Jeremy Avigad notes, setprod needs the same treatment \dots *}
 | 
| 12396 | 816 | |
| 817 | lemma setsum_empty [simp]: "setsum f {} = 0"
 | |
| 818 | by (simp add: setsum_def) | |
| 819 | ||
| 820 | lemma setsum_insert [simp]: | |
| 821 | "finite F ==> a \<notin> F ==> setsum f (insert a F) = f a + setsum f F" | |
| 15047 | 822 | by (simp add: setsum_def LC.fold_insert [OF LC.intro] add_left_commute) | 
| 12396 | 823 | |
| 14944 | 824 | lemma setsum_reindex [rule_format]: | 
| 825 | "finite B ==> inj_on f B --> setsum h (f ` B) = setsum (h \<circ> f) B" | |
| 15111 | 826 | by (rule finite_induct, auto) | 
| 12396 | 827 | |
| 14944 | 828 | lemma setsum_reindex_id: | 
| 829 | "finite B ==> inj_on f B ==> setsum f B = setsum id (f ` B)" | |
| 14485 | 830 | by (auto simp add: setsum_reindex id_o) | 
| 12396 | 831 | |
| 832 | lemma setsum_cong: | |
| 833 | "A = B ==> (!!x. x:B ==> f x = g x) ==> setsum f A = setsum g B" | |
| 834 | apply (case_tac "finite B") | |
| 14208 | 835 | prefer 2 apply (simp add: setsum_def, simp) | 
| 12396 | 836 | apply (subgoal_tac "ALL C. C <= B --> (ALL x:C. f x = g x) --> setsum f C = setsum g C") | 
| 837 | apply simp | |
| 14208 | 838 | apply (erule finite_induct, simp) | 
| 839 | apply (simp add: subset_insert_iff, clarify) | |
| 12396 | 840 | apply (subgoal_tac "finite C") | 
| 841 | prefer 2 apply (blast dest: finite_subset [COMP swap_prems_rl]) | |
| 842 |   apply (subgoal_tac "C = insert x (C - {x})")
 | |
| 843 | prefer 2 apply blast | |
| 844 | apply (erule ssubst) | |
| 845 | apply (drule spec) | |
| 846 | apply (erule (1) notE impE) | |
| 14302 | 847 | apply (simp add: Ball_def del:insert_Diff_single) | 
| 12396 | 848 | done | 
| 849 | ||
| 14944 | 850 | lemma setsum_reindex_cong: | 
| 851 | "[|finite A; inj_on f A; B = f ` A; !!a. g a = h (f a)|] | |
| 852 | ==> setsum h B = setsum g A" | |
| 853 | by (simp add: setsum_reindex cong: setsum_cong) | |
| 854 | ||
| 14485 | 855 | lemma setsum_0: "setsum (%i. 0) A = 0" | 
| 856 | apply (case_tac "finite A") | |
| 857 | prefer 2 apply (simp add: setsum_def) | |
| 858 | apply (erule finite_induct, auto) | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 859 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 860 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 861 | lemma setsum_0': "ALL a:F. f a = 0 ==> setsum f F = 0" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 862 | apply (subgoal_tac "setsum f F = setsum (%x. 0) F") | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 863 | apply (erule ssubst, rule setsum_0) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 864 | apply (rule setsum_cong, auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 865 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 866 | |
| 14485 | 867 | lemma card_eq_setsum: "finite A ==> card A = setsum (%x. 1) A" | 
| 868 |   -- {* Could allow many @{text "card"} proofs to be simplified. *}
 | |
| 869 | by (induct set: Finites) auto | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 870 | |
| 14485 | 871 | lemma setsum_Un_Int: "finite A ==> finite B | 
| 872 | ==> setsum g (A Un B) + setsum g (A Int B) = setsum g A + setsum g B" | |
| 873 |   -- {* The reversed orientation looks more natural, but LOOPS as a simprule! *}
 | |
| 874 | apply (induct set: Finites, simp) | |
| 14738 | 875 | apply (simp add: add_ac Int_insert_left insert_absorb) | 
| 14485 | 876 | done | 
| 877 | ||
| 878 | lemma setsum_Un_disjoint: "finite A ==> finite B | |
| 879 |   ==> A Int B = {} ==> setsum g (A Un B) = setsum g A + setsum g B"
 | |
| 880 | apply (subst setsum_Un_Int [symmetric], auto) | |
| 881 | done | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 882 | |
| 14485 | 883 | lemma setsum_UN_disjoint: | 
| 884 | "finite I ==> (ALL i:I. finite (A i)) ==> | |
| 885 |         (ALL i:I. ALL j:I. i \<noteq> j --> A i Int A j = {}) ==>
 | |
| 886 | setsum f (UNION I A) = setsum (%i. setsum f (A i)) I" | |
| 887 | apply (induct set: Finites, simp, atomize) | |
| 888 | apply (subgoal_tac "ALL i:F. x \<noteq> i") | |
| 889 | prefer 2 apply blast | |
| 890 |   apply (subgoal_tac "A x Int UNION F A = {}")
 | |
| 891 | prefer 2 apply blast | |
| 892 | apply (simp add: setsum_Un_disjoint) | |
| 893 | done | |
| 894 | ||
| 895 | lemma setsum_Union_disjoint: | |
| 896 | "finite C ==> (ALL A:C. finite A) ==> | |
| 897 |         (ALL A:C. ALL B:C. A \<noteq> B --> A Int B = {}) ==>
 | |
| 898 | setsum f (Union C) = setsum (setsum f) C" | |
| 899 | apply (frule setsum_UN_disjoint [of C id f]) | |
| 900 | apply (unfold Union_def id_def, assumption+) | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 901 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 902 | |
| 14661 | 903 | lemma setsum_Sigma: "finite A ==> ALL x:A. finite (B x) ==> | 
| 15074 | 904 | (\<Sum>x\<in>A. (\<Sum>y\<in>B x. f x y)) = | 
| 905 | (\<Sum>z\<in>(SIGMA x:A. B x). f (fst z) (snd z))" | |
| 14485 | 906 | apply (subst Sigma_def) | 
| 907 | apply (subst setsum_UN_disjoint) | |
| 908 | apply assumption | |
| 909 | apply (rule ballI) | |
| 910 | apply (drule_tac x = i in bspec, assumption) | |
| 14661 | 911 |   apply (subgoal_tac "(UN y:(B i). {(i, y)}) <= (%y. (i, y)) ` (B i)")
 | 
| 14485 | 912 | apply (rule finite_surj) | 
| 913 | apply auto | |
| 914 | apply (rule setsum_cong, rule refl) | |
| 915 | apply (subst setsum_UN_disjoint) | |
| 916 | apply (erule bspec, assumption) | |
| 917 | apply auto | |
| 918 | done | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 919 | |
| 14485 | 920 | lemma setsum_cartesian_product: "finite A ==> finite B ==> | 
| 15074 | 921 | (\<Sum>x\<in>A. (\<Sum>y\<in>B. f x y)) = | 
| 922 | (\<Sum>z\<in>A <*> B. f (fst z) (snd z))" | |
| 14485 | 923 | by (erule setsum_Sigma, auto); | 
| 924 | ||
| 925 | lemma setsum_addf: "setsum (%x. f x + g x) A = (setsum f A + setsum g A)" | |
| 926 | apply (case_tac "finite A") | |
| 927 | prefer 2 apply (simp add: setsum_def) | |
| 928 | apply (erule finite_induct, auto) | |
| 14738 | 929 | apply (simp add: add_ac) | 
| 14485 | 930 | done | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 931 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 932 | subsubsection {* Properties in more restricted classes of structures *}
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 933 | |
| 14485 | 934 | lemma setsum_SucD: "setsum f A = Suc n ==> EX a:A. 0 < f a" | 
| 935 | apply (case_tac "finite A") | |
| 936 | prefer 2 apply (simp add: setsum_def) | |
| 937 | apply (erule rev_mp) | |
| 938 | apply (erule finite_induct, auto) | |
| 939 | done | |
| 940 | ||
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 941 | lemma setsum_eq_0_iff [simp]: | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 942 | "finite F ==> (setsum f F = 0) = (ALL a:F. f a = (0::nat))" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 943 | by (induct set: Finites) auto | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 944 | |
| 15047 | 945 | lemma setsum_constant_nat: | 
| 15074 | 946 | "finite A ==> (\<Sum>x\<in>A. y) = (card A) * y" | 
| 15047 | 947 |   -- {* Generalized to any @{text comm_semiring_1_cancel} in
 | 
| 948 |         @{text IntDef} as @{text setsum_constant}. *}
 | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 949 | by (erule finite_induct, auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 950 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 951 | lemma setsum_Un: "finite A ==> finite B ==> | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 952 | (setsum f (A Un B) :: nat) = setsum f A + setsum f B - setsum f (A Int B)" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 953 |   -- {* For the natural numbers, we have subtraction. *}
 | 
| 14738 | 954 | by (subst setsum_Un_Int [symmetric], auto simp add: ring_eq_simps) | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 955 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 956 | lemma setsum_Un_ring: "finite A ==> finite B ==> | 
| 14738 | 957 | (setsum f (A Un B) :: 'a :: comm_ring_1) = | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 958 | setsum f A + setsum f B - setsum f (A Int B)" | 
| 14738 | 959 | by (subst setsum_Un_Int [symmetric], auto simp add: ring_eq_simps) | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 960 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 961 | lemma setsum_diff1: "(setsum f (A - {a}) :: nat) =
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 962 | (if a:A then setsum f A - f a else setsum f A)" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 963 | apply (case_tac "finite A") | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 964 | prefer 2 apply (simp add: setsum_def) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 965 | apply (erule finite_induct) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 966 | apply (auto simp add: insert_Diff_if) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 967 | apply (drule_tac a = a in mk_disjoint_insert, auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 968 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 969 | |
| 15124 | 970 | (* By Jeremy Siek: *) | 
| 971 | ||
| 972 | lemma setsum_diff: | |
| 973 | assumes finB: "finite B" | |
| 974 | shows "B \<subseteq> A \<Longrightarrow> (setsum f (A - B) :: nat) = (setsum f A) - (setsum f B)" | |
| 975 | using finB | |
| 976 | proof (induct) | |
| 977 |   show "setsum f (A - {}) = (setsum f A) - (setsum f {})" by simp
 | |
| 978 | next | |
| 979 | fix F x assume finF: "finite F" and xnotinF: "x \<notin> F" | |
| 980 | and xFinA: "insert x F \<subseteq> A" | |
| 981 | and IH: "F \<subseteq> A \<Longrightarrow> setsum f (A - F) = setsum f A - setsum f F" | |
| 982 | from xnotinF xFinA have xinAF: "x \<in> (A - F)" by simp | |
| 983 |   from xinAF have A: "setsum f ((A - F) - {x}) = setsum f (A - F) - f x"
 | |
| 984 | by (simp add: setsum_diff1) | |
| 985 | from xFinA have "F \<subseteq> A" by simp | |
| 986 | with IH have "setsum f (A - F) = setsum f A - setsum f F" by simp | |
| 987 |   with A have B: "setsum f ((A - F) - {x}) = setsum f A - setsum f F - f x"
 | |
| 988 | by simp | |
| 989 |   from xnotinF have "A - insert x F = (A - F) - {x}" by auto
 | |
| 990 | with B have C: "setsum f (A - insert x F) = setsum f A - setsum f F - f x" | |
| 991 | by simp | |
| 992 | from finF xnotinF have "setsum f (insert x F) = setsum f F + f x" by simp | |
| 993 | with C have "setsum f (A - insert x F) = setsum f A - setsum f (insert x F)" | |
| 994 | by simp | |
| 995 | thus "setsum f (A - insert x F) = setsum f A - setsum f (insert x F)" by simp | |
| 996 | qed | |
| 997 | ||
| 14738 | 998 | lemma setsum_negf: "finite A ==> setsum (%x. - (f x)::'a::comm_ring_1) A = | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 999 | - setsum f A" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1000 | by (induct set: Finites, auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1001 | |
| 14738 | 1002 | lemma setsum_subtractf: "finite A ==> setsum (%x. ((f x)::'a::comm_ring_1) - g x) A = | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1003 | setsum f A - setsum g A" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1004 | by (simp add: diff_minus setsum_addf setsum_negf) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1005 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1006 | lemma setsum_nonneg: "[| finite A; | 
| 14738 | 1007 | \<forall>x \<in> A. (0::'a::ordered_semidom) \<le> f x |] ==> | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1008 | 0 \<le> setsum f A"; | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1009 | apply (induct set: Finites, auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1010 | apply (subgoal_tac "0 + 0 \<le> f x + setsum f F", simp) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1011 | apply (blast intro: add_mono) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1012 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1013 | |
| 15047 | 1014 | lemma setsum_mult: | 
| 1015 |   fixes f :: "'a => ('b::semiring_0_cancel)"
 | |
| 1016 | assumes fin: "finite A" | |
| 1017 | shows "r * setsum f A = setsum (%n. r * f n) A" | |
| 1018 | using fin | |
| 1019 | proof (induct) | |
| 1020 | case empty thus ?case by simp | |
| 1021 | next | |
| 1022 | case (insert A x) | |
| 1023 | thus ?case by (simp add: right_distrib) | |
| 1024 | qed | |
| 1025 | ||
| 1026 | lemma setsum_abs: | |
| 1027 |   fixes f :: "'a => ('b::lordered_ab_group_abs)"
 | |
| 1028 | assumes fin: "finite A" | |
| 1029 | shows "abs (setsum f A) \<le> setsum (%i. abs(f i)) A" | |
| 1030 | using fin | |
| 1031 | proof (induct) | |
| 1032 | case empty thus ?case by simp | |
| 1033 | next | |
| 1034 | case (insert A x) | |
| 1035 | thus ?case by (auto intro: abs_triangle_ineq order_trans) | |
| 1036 | qed | |
| 1037 | ||
| 1038 | lemma setsum_abs_ge_zero: | |
| 1039 |   fixes f :: "'a => ('b::lordered_ab_group_abs)"
 | |
| 1040 | assumes fin: "finite A" | |
| 1041 | shows "0 \<le> setsum (%i. abs(f i)) A" | |
| 1042 | using fin | |
| 1043 | proof (induct) | |
| 1044 | case empty thus ?case by simp | |
| 1045 | next | |
| 1046 | case (insert A x) thus ?case by (auto intro: order_trans) | |
| 1047 | qed | |
| 1048 | ||
| 14485 | 1049 | subsubsection {* Cardinality of unions and Sigma sets *}
 | 
| 1050 | ||
| 1051 | lemma card_UN_disjoint: | |
| 1052 | "finite I ==> (ALL i:I. finite (A i)) ==> | |
| 1053 |         (ALL i:I. ALL j:I. i \<noteq> j --> A i Int A j = {}) ==>
 | |
| 1054 | card (UNION I A) = setsum (%i. card (A i)) I" | |
| 1055 | apply (subst card_eq_setsum) | |
| 1056 | apply (subst finite_UN, assumption+) | |
| 15047 | 1057 | apply (subgoal_tac | 
| 1058 | "setsum (%i. card (A i)) I = setsum (%i. (setsum (%x. 1) (A i))) I") | |
| 1059 | apply (simp add: setsum_UN_disjoint) | |
| 1060 | apply (simp add: setsum_constant_nat cong: setsum_cong) | |
| 14485 | 1061 | done | 
| 1062 | ||
| 1063 | lemma card_Union_disjoint: | |
| 1064 | "finite C ==> (ALL A:C. finite A) ==> | |
| 1065 |         (ALL A:C. ALL B:C. A \<noteq> B --> A Int B = {}) ==>
 | |
| 1066 | card (Union C) = setsum card C" | |
| 1067 | apply (frule card_UN_disjoint [of C id]) | |
| 1068 | apply (unfold Union_def id_def, assumption+) | |
| 1069 | done | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1070 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1071 | lemma SigmaI_insert: "y \<notin> A ==> | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1072 |   (SIGMA x:(insert y A). B x) = (({y} <*> (B y)) \<union> (SIGMA x: A. B x))"
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1073 | by auto | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1074 | |
| 14485 | 1075 | lemma card_cartesian_product_singleton: "finite A ==> | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1076 |     card({x} <*> A) = card(A)"
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1077 | apply (subgoal_tac "inj_on (%y .(x,y)) A") | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1078 | apply (frule card_image, assumption) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1079 |   apply (subgoal_tac "(Pair x ` A) = {x} <*> A")
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1080 | apply (auto simp add: inj_on_def) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1081 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1082 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1083 | lemma card_SigmaI [rule_format,simp]: "finite A ==> | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1084 | (ALL a:A. finite (B a)) --> | 
| 15074 | 1085 | card (SIGMA x: A. B x) = (\<Sum>a\<in>A. card (B a))" | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1086 | apply (erule finite_induct, auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1087 | apply (subst SigmaI_insert, assumption) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1088 | apply (subst card_Un_disjoint) | 
| 14485 | 1089 | apply (auto intro: finite_SigmaI simp add: card_cartesian_product_singleton) | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1090 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1091 | |
| 15047 | 1092 | lemma card_cartesian_product: | 
| 1093 | "[| finite A; finite B |] ==> card (A <*> B) = card(A) * card(B)" | |
| 1094 | by (simp add: setsum_constant_nat) | |
| 1095 | ||
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1096 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1097 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1098 | subsection {* Generalized product over a set *}
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1099 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1100 | constdefs | 
| 14738 | 1101 |   setprod :: "('a => 'b) => 'a set => 'b::comm_monoid_mult"
 | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1102 | "setprod f A == if finite A then fold (op * o f) 1 A else 1" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1103 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1104 | syntax | 
| 14738 | 1105 |   "_setprod" :: "idt => 'a set => 'b => 'b::comm_monoid_mult"  ("(3\<Prod>_:_. _)" [0, 51, 10] 10)
 | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1106 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1107 | syntax (xsymbols) | 
| 14738 | 1108 |   "_setprod" :: "idt => 'a set => 'b => 'b::comm_monoid_mult"  ("(3\<Prod>_\<in>_. _)" [0, 51, 10] 10)
 | 
| 14565 | 1109 | syntax (HTML output) | 
| 14738 | 1110 |   "_setprod" :: "idt => 'a set => 'b => 'b::comm_monoid_mult"  ("(3\<Prod>_\<in>_. _)" [0, 51, 10] 10)
 | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1111 | translations | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1112 |   "\<Prod>i:A. b" == "setprod (%i. b) A"  -- {* Beware of argument permutation! *}
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1113 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1114 | lemma setprod_empty [simp]: "setprod f {} = 1"
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1115 | by (auto simp add: setprod_def) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1116 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1117 | lemma setprod_insert [simp]: "[| finite A; a \<notin> A |] ==> | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1118 | setprod f (insert a A) = f a * setprod f A" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1119 | by (auto simp add: setprod_def LC_def LC.fold_insert | 
| 14738 | 1120 | mult_left_commute) | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1121 | |
| 14748 | 1122 | lemma setprod_reindex [rule_format]: | 
| 1123 | "finite B ==> inj_on f B --> setprod h (f ` B) = setprod (h \<circ> f) B" | |
| 15111 | 1124 | by (rule finite_induct, auto) | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1125 | |
| 14485 | 1126 | lemma setprod_reindex_id: "finite B ==> inj_on f B ==> | 
| 1127 | setprod f B = setprod id (f ` B)" | |
| 1128 | by (auto simp add: setprod_reindex id_o) | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1129 | |
| 14661 | 1130 | lemma setprod_reindex_cong: "finite A ==> inj_on f A ==> | 
| 14485 | 1131 | B = f ` A ==> g = h \<circ> f ==> setprod h B = setprod g A" | 
| 1132 | by (frule setprod_reindex, assumption, simp) | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1133 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1134 | lemma setprod_cong: | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1135 | "A = B ==> (!!x. x:B ==> f x = g x) ==> setprod f A = setprod g B" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1136 | apply (case_tac "finite B") | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1137 | prefer 2 apply (simp add: setprod_def, simp) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1138 | apply (subgoal_tac "ALL C. C <= B --> (ALL x:C. f x = g x) --> setprod f C = setprod g C") | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1139 | apply simp | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1140 | apply (erule finite_induct, simp) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1141 | apply (simp add: subset_insert_iff, clarify) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1142 | apply (subgoal_tac "finite C") | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1143 | prefer 2 apply (blast dest: finite_subset [COMP swap_prems_rl]) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1144 |   apply (subgoal_tac "C = insert x (C - {x})")
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1145 | prefer 2 apply blast | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1146 | apply (erule ssubst) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1147 | apply (drule spec) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1148 | apply (erule (1) notE impE) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1149 | apply (simp add: Ball_def del:insert_Diff_single) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1150 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1151 | |
| 14485 | 1152 | lemma setprod_1: "setprod (%i. 1) A = 1" | 
| 1153 | apply (case_tac "finite A") | |
| 14738 | 1154 | apply (erule finite_induct, auto simp add: mult_ac) | 
| 14485 | 1155 | apply (simp add: setprod_def) | 
| 1156 | done | |
| 1157 | ||
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1158 | lemma setprod_1': "ALL a:F. f a = 1 ==> setprod f F = 1" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1159 | apply (subgoal_tac "setprod f F = setprod (%x. 1) F") | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1160 | apply (erule ssubst, rule setprod_1) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1161 | apply (rule setprod_cong, auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1162 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1163 | |
| 14485 | 1164 | lemma setprod_Un_Int: "finite A ==> finite B | 
| 1165 | ==> setprod g (A Un B) * setprod g (A Int B) = setprod g A * setprod g B" | |
| 1166 | apply (induct set: Finites, simp) | |
| 14738 | 1167 | apply (simp add: mult_ac insert_absorb) | 
| 1168 | apply (simp add: mult_ac Int_insert_left insert_absorb) | |
| 14485 | 1169 | done | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1170 | |
| 14485 | 1171 | lemma setprod_Un_disjoint: "finite A ==> finite B | 
| 1172 |   ==> A Int B = {} ==> setprod g (A Un B) = setprod g A * setprod g B"
 | |
| 14738 | 1173 | apply (subst setprod_Un_Int [symmetric], auto simp add: mult_ac) | 
| 14485 | 1174 | done | 
| 1175 | ||
| 1176 | lemma setprod_UN_disjoint: | |
| 1177 | "finite I ==> (ALL i:I. finite (A i)) ==> | |
| 1178 |         (ALL i:I. ALL j:I. i \<noteq> j --> A i Int A j = {}) ==>
 | |
| 1179 | setprod f (UNION I A) = setprod (%i. setprod f (A i)) I" | |
| 1180 | apply (induct set: Finites, simp, atomize) | |
| 1181 | apply (subgoal_tac "ALL i:F. x \<noteq> i") | |
| 1182 | prefer 2 apply blast | |
| 1183 |   apply (subgoal_tac "A x Int UNION F A = {}")
 | |
| 1184 | prefer 2 apply blast | |
| 1185 | apply (simp add: setprod_Un_disjoint) | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1186 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1187 | |
| 14485 | 1188 | lemma setprod_Union_disjoint: | 
| 1189 | "finite C ==> (ALL A:C. finite A) ==> | |
| 1190 |         (ALL A:C. ALL B:C. A \<noteq> B --> A Int B = {}) ==>
 | |
| 1191 | setprod f (Union C) = setprod (setprod f) C" | |
| 1192 | apply (frule setprod_UN_disjoint [of C id f]) | |
| 1193 | apply (unfold Union_def id_def, assumption+) | |
| 1194 | done | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1195 | |
| 14661 | 1196 | lemma setprod_Sigma: "finite A ==> ALL x:A. finite (B x) ==> | 
| 1197 | (\<Prod>x:A. (\<Prod>y: B x. f x y)) = | |
| 1198 | (\<Prod>z:(SIGMA x:A. B x). f (fst z) (snd z))" | |
| 14485 | 1199 | apply (subst Sigma_def) | 
| 1200 | apply (subst setprod_UN_disjoint) | |
| 1201 | apply assumption | |
| 1202 | apply (rule ballI) | |
| 1203 | apply (drule_tac x = i in bspec, assumption) | |
| 14661 | 1204 |   apply (subgoal_tac "(UN y:(B i). {(i, y)}) <= (%y. (i, y)) ` (B i)")
 | 
| 14485 | 1205 | apply (rule finite_surj) | 
| 1206 | apply auto | |
| 1207 | apply (rule setprod_cong, rule refl) | |
| 1208 | apply (subst setprod_UN_disjoint) | |
| 1209 | apply (erule bspec, assumption) | |
| 1210 | apply auto | |
| 1211 | done | |
| 1212 | ||
| 14661 | 1213 | lemma setprod_cartesian_product: "finite A ==> finite B ==> | 
| 1214 | (\<Prod>x:A. (\<Prod>y: B. f x y)) = | |
| 1215 | (\<Prod>z:(A <*> B). f (fst z) (snd z))" | |
| 14485 | 1216 | by (erule setprod_Sigma, auto) | 
| 1217 | ||
| 1218 | lemma setprod_timesf: "setprod (%x. f x * g x) A = | |
| 1219 | (setprod f A * setprod g A)" | |
| 1220 | apply (case_tac "finite A") | |
| 14738 | 1221 | prefer 2 apply (simp add: setprod_def mult_ac) | 
| 14485 | 1222 | apply (erule finite_induct, auto) | 
| 14738 | 1223 | apply (simp add: mult_ac) | 
| 14485 | 1224 | done | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1225 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1226 | subsubsection {* Properties in more restricted classes of structures *}
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1227 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1228 | lemma setprod_eq_1_iff [simp]: | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1229 | "finite F ==> (setprod f F = 1) = (ALL a:F. f a = (1::nat))" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1230 | by (induct set: Finites) auto | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1231 | |
| 15004 | 1232 | lemma setprod_constant: "finite A ==> (\<Prod>x: A. (y::'a::recpower)) = y^(card A)" | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1233 | apply (erule finite_induct) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1234 | apply (auto simp add: power_Suc) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1235 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1236 | |
| 15004 | 1237 | lemma setprod_zero: | 
| 1238 | "finite A ==> EX x: A. f x = (0::'a::comm_semiring_1_cancel) ==> setprod f A = 0" | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1239 | apply (induct set: Finites, force, clarsimp) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1240 | apply (erule disjE, auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1241 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1242 | |
| 15004 | 1243 | lemma setprod_nonneg [rule_format]: | 
| 1244 | "(ALL x: A. (0::'a::ordered_idom) \<le> f x) --> 0 \<le> setprod f A" | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1245 | apply (case_tac "finite A") | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1246 | apply (induct set: Finites, force, clarsimp) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1247 | apply (subgoal_tac "0 * 0 \<le> f x * setprod f F", force) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1248 | apply (rule mult_mono, assumption+) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1249 | apply (auto simp add: setprod_def) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1250 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1251 | |
| 14738 | 1252 | lemma setprod_pos [rule_format]: "(ALL x: A. (0::'a::ordered_idom) < f x) | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1253 | --> 0 < setprod f A" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1254 | apply (case_tac "finite A") | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1255 | apply (induct set: Finites, force, clarsimp) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1256 | apply (subgoal_tac "0 * 0 < f x * setprod f F", force) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1257 | apply (rule mult_strict_mono, assumption+) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1258 | apply (auto simp add: setprod_def) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1259 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1260 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1261 | lemma setprod_nonzero [rule_format]: | 
| 14738 | 1262 | "(ALL x y. (x::'a::comm_semiring_1_cancel) * y = 0 --> x = 0 | y = 0) ==> | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1263 | finite A ==> (ALL x: A. f x \<noteq> (0::'a)) --> setprod f A \<noteq> 0" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1264 | apply (erule finite_induct, auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1265 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1266 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1267 | lemma setprod_zero_eq: | 
| 14738 | 1268 | "(ALL x y. (x::'a::comm_semiring_1_cancel) * y = 0 --> x = 0 | y = 0) ==> | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1269 | finite A ==> (setprod f A = (0::'a)) = (EX x: A. f x = 0)" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1270 | apply (insert setprod_zero [of A f] setprod_nonzero [of A f], blast) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1271 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1272 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1273 | lemma setprod_nonzero_field: | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1274 | "finite A ==> (ALL x: A. f x \<noteq> (0::'a::field)) ==> setprod f A \<noteq> 0" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1275 | apply (rule setprod_nonzero, auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1276 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1277 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1278 | lemma setprod_zero_eq_field: | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1279 | "finite A ==> (setprod f A = (0::'a::field)) = (EX x: A. f x = 0)" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1280 | apply (rule setprod_zero_eq, auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1281 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1282 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1283 | lemma setprod_Un: "finite A ==> finite B ==> (ALL x: A Int B. f x \<noteq> 0) ==> | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1284 |     (setprod f (A Un B) :: 'a ::{field})
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1285 | = setprod f A * setprod f B / setprod f (A Int B)" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1286 | apply (subst setprod_Un_Int [symmetric], auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1287 | apply (subgoal_tac "finite (A Int B)") | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1288 | apply (frule setprod_nonzero_field [of "A Int B" f], assumption) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1289 | apply (subst times_divide_eq_right [THEN sym], auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1290 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1291 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1292 | lemma setprod_diff1: "finite A ==> f a \<noteq> 0 ==> | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1293 |     (setprod f (A - {a}) :: 'a :: {field}) =
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1294 | (if a:A then setprod f A / f a else setprod f A)" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1295 | apply (erule finite_induct) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1296 | apply (auto simp add: insert_Diff_if) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1297 | apply (subgoal_tac "f a * setprod f F / f a = setprod f F * f a / f a") | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1298 | apply (erule ssubst) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1299 | apply (subst times_divide_eq_right [THEN sym]) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1300 | apply (auto simp add: mult_ac) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1301 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1302 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1303 | lemma setprod_inversef: "finite A ==> | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1304 |     ALL x: A. f x \<noteq> (0::'a::{field,division_by_zero}) ==>
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1305 | setprod (inverse \<circ> f) A = inverse (setprod f A)" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1306 | apply (erule finite_induct) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1307 | apply (simp, simp) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1308 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1309 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1310 | lemma setprod_dividef: | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1311 | "[|finite A; | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1312 |         \<forall>x \<in> A. g x \<noteq> (0::'a::{field,division_by_zero})|]
 | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1313 | ==> setprod (%x. f x / g x) A = setprod f A / setprod g A" | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1314 | apply (subgoal_tac | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1315 | "setprod (%x. f x / g x) A = setprod (%x. f x * (inverse \<circ> g) x) A") | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1316 | apply (erule ssubst) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1317 | apply (subst divide_inverse) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1318 | apply (subst setprod_timesf) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1319 | apply (subst setprod_inversef, assumption+, rule refl) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1320 | apply (rule setprod_cong, rule refl) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1321 | apply (subst divide_inverse, auto) | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1322 | done | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1323 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1324 | |
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1325 | subsection{* Min and Max of finite linearly ordered sets *}
 | 
| 13490 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1326 | |
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1327 | text{* Seemed easier to define directly than via fold. *}
 | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1328 | |
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1329 | lemma ex_Max: fixes S :: "('a::linorder)set"
 | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1330 |   assumes fin: "finite S" shows "S \<noteq> {} ==> \<exists>m\<in>S. \<forall>s \<in> S. s \<le> m"
 | 
| 13490 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1331 | using fin | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1332 | proof (induct) | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1333 | case empty thus ?case by simp | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1334 | next | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1335 | case (insert S x) | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1336 | show ?case | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1337 | proof (cases) | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1338 |     assume "S = {}" thus ?thesis by simp
 | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1339 | next | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1340 |     assume nonempty: "S \<noteq> {}"
 | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1341 | then obtain m where m: "m\<in>S" "\<forall>s\<in>S. s \<le> m" using insert by blast | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1342 | show ?thesis | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1343 | proof (cases) | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1344 | assume "x \<le> m" thus ?thesis using m by blast | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1345 | next | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1346 | assume "~ x \<le> m" thus ?thesis using m | 
| 14661 | 1347 | by(simp add:linorder_not_le order_less_le)(blast intro: order_trans) | 
| 13490 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1348 | qed | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1349 | qed | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1350 | qed | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1351 | |
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1352 | lemma ex_Min: fixes S :: "('a::linorder)set"
 | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1353 |   assumes fin: "finite S" shows "S \<noteq> {} ==> \<exists>m\<in>S. \<forall>s \<in> S. m \<le> s"
 | 
| 13490 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1354 | using fin | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1355 | proof (induct) | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1356 | case empty thus ?case by simp | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1357 | next | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1358 | case (insert S x) | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1359 | show ?case | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1360 | proof (cases) | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1361 |     assume "S = {}" thus ?thesis by simp
 | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1362 | next | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1363 |     assume nonempty: "S \<noteq> {}"
 | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1364 | then obtain m where m: "m\<in>S" "\<forall>s\<in>S. m \<le> s" using insert by blast | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1365 | show ?thesis | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1366 | proof (cases) | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1367 | assume "m \<le> x" thus ?thesis using m by blast | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1368 | next | 
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1369 | assume "~ m \<le> x" thus ?thesis using m | 
| 14661 | 1370 | by(simp add:linorder_not_le order_less_le)(blast intro: order_trans) | 
| 13490 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1371 | qed | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1372 | qed | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1373 | qed | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1374 | |
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1375 | constdefs | 
| 14661 | 1376 |   Min :: "('a::linorder)set => 'a"
 | 
| 1377 | "Min S == THE m. m \<in> S \<and> (\<forall>s \<in> S. m \<le> s)" | |
| 13490 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1378 | |
| 14661 | 1379 |   Max :: "('a::linorder)set => 'a"
 | 
| 1380 | "Max S == THE m. m \<in> S \<and> (\<forall>s \<in> S. s \<le> m)" | |
| 13490 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1381 | |
| 14661 | 1382 | lemma Min [simp]: | 
| 1383 |   assumes a: "finite S"  "S \<noteq> {}"
 | |
| 1384 | shows "Min S \<in> S \<and> (\<forall>s \<in> S. Min S \<le> s)" (is "?P(Min S)") | |
| 13490 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1385 | proof (unfold Min_def, rule theI') | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1386 | show "\<exists>!m. ?P m" | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1387 | proof (rule ex_ex1I) | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1388 | show "\<exists>m. ?P m" using ex_Min[OF a] by blast | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1389 | next | 
| 14661 | 1390 | fix m1 m2 assume "?P m1" and "?P m2" | 
| 1391 | thus "m1 = m2" by (blast dest: order_antisym) | |
| 13490 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1392 | qed | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1393 | qed | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1394 | |
| 14661 | 1395 | lemma Max [simp]: | 
| 1396 |   assumes a: "finite S"  "S \<noteq> {}"
 | |
| 1397 | shows "Max S \<in> S \<and> (\<forall>s \<in> S. s \<le> Max S)" (is "?P(Max S)") | |
| 13490 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1398 | proof (unfold Max_def, rule theI') | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1399 | show "\<exists>!m. ?P m" | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1400 | proof (rule ex_ex1I) | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1401 | show "\<exists>m. ?P m" using ex_Max[OF a] by blast | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1402 | next | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1403 | fix m1 m2 assume "?P m1" "?P m2" | 
| 14661 | 1404 | thus "m1 = m2" by (blast dest: order_antisym) | 
| 13490 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1405 | qed | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1406 | qed | 
| 
44bdc150211b
Added Mi and Max on sets, hid Min and Pls on numerals.
 nipkow parents: 
13421diff
changeset | 1407 | |
| 14661 | 1408 | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1409 | subsection {* Theorems about @{text "choose"} *}
 | 
| 12396 | 1410 | |
| 1411 | text {*
 | |
| 1412 |   \medskip Basic theorem about @{text "choose"}.  By Florian
 | |
| 14661 | 1413 | Kamm\"uller, tidied by LCP. | 
| 12396 | 1414 | *} | 
| 1415 | ||
| 1416 | lemma card_s_0_eq_empty: | |
| 1417 |     "finite A ==> card {B. B \<subseteq> A & card B = 0} = 1"
 | |
| 1418 | apply (simp cong add: conj_cong add: finite_subset [THEN card_0_eq]) | |
| 1419 | apply (simp cong add: rev_conj_cong) | |
| 1420 | done | |
| 1421 | ||
| 1422 | lemma choose_deconstruct: "finite M ==> x \<notin> M | |
| 1423 |   ==> {s. s <= insert x M & card(s) = Suc k}
 | |
| 1424 |        = {s. s <= M & card(s) = Suc k} Un
 | |
| 1425 |          {s. EX t. t <= M & card(t) = k & s = insert x t}"
 | |
| 1426 | apply safe | |
| 1427 | apply (auto intro: finite_subset [THEN card_insert_disjoint]) | |
| 1428 |   apply (drule_tac x = "xa - {x}" in spec)
 | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1429 | apply (subgoal_tac "x \<notin> xa", auto) | 
| 12396 | 1430 | apply (erule rev_mp, subst card_Diff_singleton) | 
| 1431 | apply (auto intro: finite_subset) | |
| 1432 | done | |
| 1433 | ||
| 1434 | lemma card_inj_on_le: | |
| 14748 | 1435 | "[|inj_on f A; f ` A \<subseteq> B; finite B |] ==> card A \<le> card B" | 
| 1436 | apply (subgoal_tac "finite A") | |
| 1437 | apply (force intro: card_mono simp add: card_image [symmetric]) | |
| 14944 | 1438 | apply (blast intro: finite_imageD dest: finite_subset) | 
| 14748 | 1439 | done | 
| 12396 | 1440 | |
| 14430 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1441 | lemma card_bij_eq: | 
| 
5cb24165a2e1
new material from Avigad, and simplified treatment of division by 0
 paulson parents: 
14331diff
changeset | 1442 | "[|inj_on f A; f ` A \<subseteq> B; inj_on g B; g ` B \<subseteq> A; | 
| 13595 | 1443 | finite A; finite B |] ==> card A = card B" | 
| 12396 | 1444 | by (auto intro: le_anti_sym card_inj_on_le) | 
| 1445 | ||
| 13595 | 1446 | text{*There are as many subsets of @{term A} having cardinality @{term k}
 | 
| 1447 | as there are sets obtained from the former by inserting a fixed element | |
| 1448 |  @{term x} into each.*}
 | |
| 1449 | lemma constr_bij: | |
| 1450 | "[|finite A; x \<notin> A|] ==> | |
| 1451 |     card {B. EX C. C <= A & card(C) = k & B = insert x C} =
 | |
| 12396 | 1452 |     card {B. B <= A & card(B) = k}"
 | 
| 1453 |   apply (rule_tac f = "%s. s - {x}" and g = "insert x" in card_bij_eq)
 | |
| 13595 | 1454 | apply (auto elim!: equalityE simp add: inj_on_def) | 
| 1455 | apply (subst Diff_insert0, auto) | |
| 1456 |    txt {* finiteness of the two sets *}
 | |
| 1457 | apply (rule_tac [2] B = "Pow (A)" in finite_subset) | |
| 1458 | apply (rule_tac B = "Pow (insert x A)" in finite_subset) | |
| 1459 | apply fast+ | |
| 12396 | 1460 | done | 
| 1461 | ||
| 1462 | text {*
 | |
| 1463 | Main theorem: combinatorial statement about number of subsets of a set. | |
| 1464 | *} | |
| 1465 | ||
| 1466 | lemma n_sub_lemma: | |
| 1467 |   "!!A. finite A ==> card {B. B <= A & card B = k} = (card A choose k)"
 | |
| 1468 | apply (induct k) | |
| 14208 | 1469 | apply (simp add: card_s_0_eq_empty, atomize) | 
| 12396 | 1470 | apply (rotate_tac -1, erule finite_induct) | 
| 13421 | 1471 | apply (simp_all (no_asm_simp) cong add: conj_cong | 
| 1472 | add: card_s_0_eq_empty choose_deconstruct) | |
| 12396 | 1473 | apply (subst card_Un_disjoint) | 
| 1474 | prefer 4 apply (force simp add: constr_bij) | |
| 1475 | prefer 3 apply force | |
| 1476 | prefer 2 apply (blast intro: finite_Pow_iff [THEN iffD2] | |
| 1477 | finite_subset [of _ "Pow (insert x F)", standard]) | |
| 1478 | apply (blast intro: finite_Pow_iff [THEN iffD2, THEN [2] finite_subset]) | |
| 1479 | done | |
| 1480 | ||
| 13421 | 1481 | theorem n_subsets: | 
| 1482 |     "finite A ==> card {B. B <= A & card B = k} = (card A choose k)"
 | |
| 12396 | 1483 | by (simp add: n_sub_lemma) | 
| 1484 | ||
| 1485 | end |