src/HOL/Finite_Set.thy
changeset 24342 a1d489e254ec
parent 24303 32b67bdf2c3a
child 24380 c215e256beca
equal deleted inserted replaced
24341:7b8da2396c49 24342:a1d489e254ec
  1773    apply (simp add: card_image Pow_insert)
  1773    apply (simp add: card_image Pow_insert)
  1774   apply (unfold inj_on_def)
  1774   apply (unfold inj_on_def)
  1775   apply (blast elim!: equalityE)
  1775   apply (blast elim!: equalityE)
  1776   done
  1776   done
  1777 
  1777 
  1778 text {* Relates to equivalence classes.  Based on a theorem of
  1778 text {* Relates to equivalence classes.  Based on a theorem of F. Kammüller.  *}
  1779 F. Kamm�ller's.  *}
       
  1780 
  1779 
  1781 lemma dvd_partition:
  1780 lemma dvd_partition:
  1782   "finite (Union C) ==>
  1781   "finite (Union C) ==>
  1783     ALL c : C. k dvd card c ==>
  1782     ALL c : C. k dvd card c ==>
  1784     (ALL c1: C. ALL c2: C. c1 \<noteq> c2 --> c1 Int c2 = {}) ==>
  1783     (ALL c1: C. ALL c2: C. c1 \<noteq> c2 --> c1 Int c2 = {}) ==>
  2274 done
  2273 done
  2275 
  2274 
  2276 
  2275 
  2277 subsection {* Finiteness and quotients *}
  2276 subsection {* Finiteness and quotients *}
  2278 
  2277 
  2279 text {*Suggested by Florian Kamm�ller*}
  2278 text {*Suggested by Florian Kammüller*}
  2280 
  2279 
  2281 lemma finite_quotient: "finite A ==> r \<subseteq> A \<times> A ==> finite (A//r)"
  2280 lemma finite_quotient: "finite A ==> r \<subseteq> A \<times> A ==> finite (A//r)"
  2282   -- {* recall @{thm equiv_type} *}
  2281   -- {* recall @{thm equiv_type} *}
  2283   apply (rule finite_subset)
  2282   apply (rule finite_subset)
  2284    apply (erule_tac [2] finite_Pow_iff [THEN iffD2])
  2283    apply (erule_tac [2] finite_Pow_iff [THEN iffD2])
  2357 
  2356 
  2358 lemmas int_setsum = of_nat_setsum [where 'a=int]
  2357 lemmas int_setsum = of_nat_setsum [where 'a=int]
  2359 lemmas int_setprod = of_nat_setprod [where 'a=int]
  2358 lemmas int_setprod = of_nat_setprod [where 'a=int]
  2360 
  2359 
  2361 
  2360 
  2362 locale Lattice = lattice -- {* we do not pollute the @{text lattice} clas *}
  2361 context lattice
  2363 begin
  2362 begin
  2364 
  2363 
  2365 definition
  2364 definition
  2366   Inf :: "'a set \<Rightarrow> 'a" ("\<Sqinter>_" [900] 900)
  2365   Inf_fin :: "'a set \<Rightarrow> 'a" ("\<Sqinter>\<^bsub>fin\<^esub>_" [900] 900)
  2367 where
  2366 where
  2368   "Inf = fold1 (op \<sqinter>)"
  2367   "Inf_fin = fold1 (op \<sqinter>)"
  2369 
  2368 
  2370 definition
  2369 definition
  2371   Sup :: "'a set \<Rightarrow> 'a" ("\<Squnion>_" [900] 900)
  2370   Sup_fin :: "'a set \<Rightarrow> 'a" ("\<Squnion>\<^bsub>fin\<^esub>_" [900] 900)
  2372 where
  2371 where
  2373   "Sup = fold1 (op \<squnion>)"
  2372   "Sup_fin = fold1 (op \<squnion>)"
  2374 
  2373 
  2375 end
  2374 end context lattice begin
  2376 
  2375 
  2377 locale Distrib_Lattice = distrib_lattice + Lattice
  2376 lemma Inf_le_Sup [simp]: "\<lbrakk> finite A; A \<noteq> {} \<rbrakk> \<Longrightarrow> \<Sqinter>\<^bsub>fin\<^esub>A \<sqsubseteq> \<Squnion>\<^bsub>fin\<^esub>A"
  2378 
  2377 apply(unfold Sup_fin_def Inf_fin_def)
  2379 lemma (in Lattice) Inf_le_Sup[simp]: "\<lbrakk> finite A; A \<noteq> {} \<rbrakk> \<Longrightarrow> \<Sqinter>A \<sqsubseteq> \<Squnion>A"
       
  2380 apply(unfold Sup_def Inf_def)
       
  2381 apply(subgoal_tac "EX a. a:A")
  2378 apply(subgoal_tac "EX a. a:A")
  2382 prefer 2 apply blast
  2379 prefer 2 apply blast
  2383 apply(erule exE)
  2380 apply(erule exE)
  2384 apply(rule order_trans)
  2381 apply(rule order_trans)
  2385 apply(erule (2) ACIfSL.fold1_belowI[OF ACIfSL_inf])
  2382 apply(erule (2) ACIfSL.fold1_belowI[OF ACIfSL_inf])
  2386 apply(erule (2) ACIfSL.fold1_belowI[OF ACIfSL_sup])
  2383 apply(erule (2) ACIfSL.fold1_belowI[OF ACIfSL_sup])
  2387 done
  2384 done
  2388 
  2385 
  2389 lemma (in Lattice) sup_Inf_absorb[simp]:
  2386 lemma sup_Inf_absorb [simp]:
  2390   "\<lbrakk> finite A; A \<noteq> {}; a \<in> A \<rbrakk> \<Longrightarrow> (a \<squnion> \<Sqinter>A) = a"
  2387   "\<lbrakk> finite A; A \<noteq> {}; a \<in> A \<rbrakk> \<Longrightarrow> (a \<squnion> \<Sqinter>\<^bsub>fin\<^esub>A) = a"
  2391 apply(subst sup_commute)
  2388 apply(subst sup_commute)
  2392 apply(simp add:Inf_def sup_absorb2 ACIfSL.fold1_belowI[OF ACIfSL_inf])
  2389 apply(simp add: Inf_fin_def sup_absorb2 ACIfSL.fold1_belowI [OF ACIfSL_inf])
  2393 done
  2390 done
  2394 
  2391 
  2395 lemma (in Lattice) inf_Sup_absorb[simp]:
  2392 lemma inf_Sup_absorb [simp]:
  2396   "\<lbrakk> finite A; A \<noteq> {}; a \<in> A \<rbrakk> \<Longrightarrow> (a \<sqinter> \<Squnion>A) = a"
  2393   "\<lbrakk> finite A; A \<noteq> {}; a \<in> A \<rbrakk> \<Longrightarrow> (a \<sqinter> \<Squnion>\<^bsub>fin\<^esub>A) = a"
  2397 by(simp add:Sup_def inf_absorb1 ACIfSL.fold1_belowI[OF ACIfSL_sup])
  2394 by(simp add: Sup_fin_def inf_absorb1 ACIfSL.fold1_belowI [OF ACIfSL_sup])
  2398 
  2395 
  2399 lemma (in Distrib_Lattice) sup_Inf1_distrib:
  2396 end
  2400  "finite A \<Longrightarrow> A \<noteq> {} \<Longrightarrow> (x \<squnion> \<Sqinter>A) = \<Sqinter>{x \<squnion> a|a. a \<in> A}"
  2397 
  2401 apply(simp add:Inf_def image_def
  2398 context distrib_lattice
       
  2399 begin
       
  2400 
       
  2401 lemma sup_Inf1_distrib:
       
  2402  "finite A \<Longrightarrow> A \<noteq> {} \<Longrightarrow> (x \<squnion> \<Sqinter>\<^bsub>fin\<^esub>A) = \<Sqinter>\<^bsub>fin\<^esub>{x \<squnion> a|a. a \<in> A}"
       
  2403 apply(simp add: Inf_fin_def image_def
  2402   ACIf.hom_fold1_commute[OF ACIf_inf, where h="sup x", OF sup_inf_distrib1])
  2404   ACIf.hom_fold1_commute[OF ACIf_inf, where h="sup x", OF sup_inf_distrib1])
  2403 apply(rule arg_cong, blast)
  2405 apply(rule arg_cong, blast)
  2404 done
  2406 done
  2405 
  2407 
  2406 
  2408 lemma sup_Inf2_distrib:
  2407 lemma (in Distrib_Lattice) sup_Inf2_distrib:
  2409   assumes A: "finite A" "A \<noteq> {}" and B: "finite B" "B \<noteq> {}"
  2408 assumes A: "finite A" "A \<noteq> {}" and B: "finite B" "B \<noteq> {}"
  2410   shows "(\<Sqinter>\<^bsub>fin\<^esub>A \<squnion> \<Sqinter>\<^bsub>fin\<^esub>B) = \<Sqinter>\<^bsub>fin\<^esub>{a \<squnion> b|a b. a \<in> A \<and> b \<in> B}"
  2409 shows "(\<Sqinter>A \<squnion> \<Sqinter>B) = \<Sqinter>{a \<squnion> b|a b. a \<in> A \<and> b \<in> B}"
  2411 using A proof (induct rule: finite_ne_induct)
  2410 using A
       
  2411 proof (induct rule: finite_ne_induct)
       
  2412   case singleton thus ?case
  2412   case singleton thus ?case
  2413     by (simp add: sup_Inf1_distrib[OF B] fold1_singleton_def[OF Inf_def])
  2413     by (simp add: sup_Inf1_distrib [OF B] fold1_singleton_def [OF Inf_fin_def])
  2414 next
  2414 next
  2415   case (insert x A)
  2415   case (insert x A)
  2416   have finB: "finite {x \<squnion> b |b. b \<in> B}"
  2416   have finB: "finite {x \<squnion> b |b. b \<in> B}"
  2417     by(rule finite_surj[where f = "%b. x \<squnion> b", OF B(1)], auto)
  2417     by(rule finite_surj[where f = "%b. x \<squnion> b", OF B(1)], auto)
  2418   have finAB: "finite {a \<squnion> b |a b. a \<in> A \<and> b \<in> B}"
  2418   have finAB: "finite {a \<squnion> b |a b. a \<in> A \<and> b \<in> B}"
  2420     have "{a \<squnion> b |a b. a \<in> A \<and> b \<in> B} = (UN a:A. UN b:B. {a \<squnion> b})"
  2420     have "{a \<squnion> b |a b. a \<in> A \<and> b \<in> B} = (UN a:A. UN b:B. {a \<squnion> b})"
  2421       by blast
  2421       by blast
  2422     thus ?thesis by(simp add: insert(1) B(1))
  2422     thus ?thesis by(simp add: insert(1) B(1))
  2423   qed
  2423   qed
  2424   have ne: "{a \<squnion> b |a b. a \<in> A \<and> b \<in> B} \<noteq> {}" using insert B by blast
  2424   have ne: "{a \<squnion> b |a b. a \<in> A \<and> b \<in> B} \<noteq> {}" using insert B by blast
  2425   have "\<Sqinter>(insert x A) \<squnion> \<Sqinter>B = (x \<sqinter> \<Sqinter>A) \<squnion> \<Sqinter>B"
  2425   have "\<Sqinter>\<^bsub>fin\<^esub>(insert x A) \<squnion> \<Sqinter>\<^bsub>fin\<^esub>B = (x \<sqinter> \<Sqinter>\<^bsub>fin\<^esub>A) \<squnion> \<Sqinter>\<^bsub>fin\<^esub>B"
  2426     using insert
  2426     using insert
  2427  by(simp add:ACIf.fold1_insert_idem_def[OF ACIf_inf Inf_def])
  2427  by(simp add:ACIf.fold1_insert_idem_def[OF ACIf_inf Inf_fin_def])
  2428   also have "\<dots> = (x \<squnion> \<Sqinter>B) \<sqinter> (\<Sqinter>A \<squnion> \<Sqinter>B)" by(rule sup_inf_distrib2)
  2428   also have "\<dots> = (x \<squnion> \<Sqinter>\<^bsub>fin\<^esub>B) \<sqinter> (\<Sqinter>\<^bsub>fin\<^esub>A \<squnion> \<Sqinter>\<^bsub>fin\<^esub>B)" by(rule sup_inf_distrib2)
  2429   also have "\<dots> = \<Sqinter>{x \<squnion> b|b. b \<in> B} \<sqinter> \<Sqinter>{a \<squnion> b|a b. a \<in> A \<and> b \<in> B}"
  2429   also have "\<dots> = \<Sqinter>\<^bsub>fin\<^esub>{x \<squnion> b|b. b \<in> B} \<sqinter> \<Sqinter>\<^bsub>fin\<^esub>{a \<squnion> b|a b. a \<in> A \<and> b \<in> B}"
  2430     using insert by(simp add:sup_Inf1_distrib[OF B])
  2430     using insert by(simp add:sup_Inf1_distrib[OF B])
  2431   also have "\<dots> = \<Sqinter>({x\<squnion>b |b. b \<in> B} \<union> {a\<squnion>b |a b. a \<in> A \<and> b \<in> B})"
  2431   also have "\<dots> = \<Sqinter>\<^bsub>fin\<^esub>({x\<squnion>b |b. b \<in> B} \<union> {a\<squnion>b |a b. a \<in> A \<and> b \<in> B})"
  2432     (is "_ = \<Sqinter>?M")
  2432     (is "_ = \<Sqinter>\<^bsub>fin\<^esub>?M")
  2433     using B insert
  2433     using B insert
  2434     by(simp add:Inf_def ACIf.fold1_Un2[OF ACIf_inf finB _ finAB ne])
  2434     by (simp add: Inf_fin_def ACIf.fold1_Un2[OF ACIf_inf finB _ finAB ne])
  2435   also have "?M = {a \<squnion> b |a b. a \<in> insert x A \<and> b \<in> B}"
  2435   also have "?M = {a \<squnion> b |a b. a \<in> insert x A \<and> b \<in> B}"
  2436     by blast
  2436     by blast
  2437   finally show ?case .
  2437   finally show ?case .
  2438 qed
  2438 qed
  2439 
  2439 
  2440 
  2440 lemma inf_Sup1_distrib:
  2441 lemma (in Distrib_Lattice) inf_Sup1_distrib:
  2441  "finite A \<Longrightarrow> A \<noteq> {} \<Longrightarrow> (x \<sqinter> \<Squnion>\<^bsub>fin\<^esub>A) = \<Squnion>\<^bsub>fin\<^esub>{x \<sqinter> a|a. a \<in> A}"
  2442  "finite A \<Longrightarrow> A \<noteq> {} \<Longrightarrow> (x \<sqinter> \<Squnion>A) = \<Squnion>{x \<sqinter> a|a. a \<in> A}"
  2442 apply (simp add: Sup_fin_def image_def
  2443 apply(simp add:Sup_def image_def
       
  2444   ACIf.hom_fold1_commute[OF ACIf_sup, where h="inf x", OF inf_sup_distrib1])
  2443   ACIf.hom_fold1_commute[OF ACIf_sup, where h="inf x", OF inf_sup_distrib1])
  2445 apply(rule arg_cong, blast)
  2444 apply (rule arg_cong, blast)
  2446 done
  2445 done
  2447 
  2446 
  2448 
  2447 lemma inf_Sup2_distrib:
  2449 lemma (in Distrib_Lattice) inf_Sup2_distrib:
  2448   assumes A: "finite A" "A \<noteq> {}" and B: "finite B" "B \<noteq> {}"
  2450 assumes A: "finite A" "A \<noteq> {}" and B: "finite B" "B \<noteq> {}"
  2449   shows "(\<Squnion>\<^bsub>fin\<^esub>A \<sqinter> \<Squnion>\<^bsub>fin\<^esub>B) = \<Squnion>\<^bsub>fin\<^esub>{a \<sqinter> b|a b. a \<in> A \<and> b \<in> B}"
  2451 shows "(\<Squnion>A \<sqinter> \<Squnion>B) = \<Squnion>{a \<sqinter> b|a b. a \<in> A \<and> b \<in> B}"
  2450 using A proof (induct rule: finite_ne_induct)
  2452 using A
       
  2453 proof (induct rule: finite_ne_induct)
       
  2454   case singleton thus ?case
  2451   case singleton thus ?case
  2455     by(simp add: inf_Sup1_distrib[OF B] fold1_singleton_def[OF Sup_def])
  2452     by(simp add: inf_Sup1_distrib [OF B] fold1_singleton_def [OF Sup_fin_def])
  2456 next
  2453 next
  2457   case (insert x A)
  2454   case (insert x A)
  2458   have finB: "finite {x \<sqinter> b |b. b \<in> B}"
  2455   have finB: "finite {x \<sqinter> b |b. b \<in> B}"
  2459     by(rule finite_surj[where f = "%b. x \<sqinter> b", OF B(1)], auto)
  2456     by(rule finite_surj[where f = "%b. x \<sqinter> b", OF B(1)], auto)
  2460   have finAB: "finite {a \<sqinter> b |a b. a \<in> A \<and> b \<in> B}"
  2457   have finAB: "finite {a \<sqinter> b |a b. a \<in> A \<and> b \<in> B}"
  2462     have "{a \<sqinter> b |a b. a \<in> A \<and> b \<in> B} = (UN a:A. UN b:B. {a \<sqinter> b})"
  2459     have "{a \<sqinter> b |a b. a \<in> A \<and> b \<in> B} = (UN a:A. UN b:B. {a \<sqinter> b})"
  2463       by blast
  2460       by blast
  2464     thus ?thesis by(simp add: insert(1) B(1))
  2461     thus ?thesis by(simp add: insert(1) B(1))
  2465   qed
  2462   qed
  2466   have ne: "{a \<sqinter> b |a b. a \<in> A \<and> b \<in> B} \<noteq> {}" using insert B by blast
  2463   have ne: "{a \<sqinter> b |a b. a \<in> A \<and> b \<in> B} \<noteq> {}" using insert B by blast
  2467   have "\<Squnion>(insert x A) \<sqinter> \<Squnion>B = (x \<squnion> \<Squnion>A) \<sqinter> \<Squnion>B"
  2464   have "\<Squnion>\<^bsub>fin\<^esub>(insert x A) \<sqinter> \<Squnion>\<^bsub>fin\<^esub>B = (x \<squnion> \<Squnion>\<^bsub>fin\<^esub>A) \<sqinter> \<Squnion>\<^bsub>fin\<^esub>B"
  2468     using insert by(simp add:ACIf.fold1_insert_idem_def[OF ACIf_sup Sup_def])
  2465     using insert by (simp add: ACIf.fold1_insert_idem_def [OF ACIf_sup Sup_fin_def])
  2469   also have "\<dots> = (x \<sqinter> \<Squnion>B) \<squnion> (\<Squnion>A \<sqinter> \<Squnion>B)" by(rule inf_sup_distrib2)
  2466   also have "\<dots> = (x \<sqinter> \<Squnion>\<^bsub>fin\<^esub>B) \<squnion> (\<Squnion>\<^bsub>fin\<^esub>A \<sqinter> \<Squnion>\<^bsub>fin\<^esub>B)" by(rule inf_sup_distrib2)
  2470   also have "\<dots> = \<Squnion>{x \<sqinter> b|b. b \<in> B} \<squnion> \<Squnion>{a \<sqinter> b|a b. a \<in> A \<and> b \<in> B}"
  2467   also have "\<dots> = \<Squnion>\<^bsub>fin\<^esub>{x \<sqinter> b|b. b \<in> B} \<squnion> \<Squnion>\<^bsub>fin\<^esub>{a \<sqinter> b|a b. a \<in> A \<and> b \<in> B}"
  2471     using insert by(simp add:inf_Sup1_distrib[OF B])
  2468     using insert by(simp add:inf_Sup1_distrib[OF B])
  2472   also have "\<dots> = \<Squnion>({x\<sqinter>b |b. b \<in> B} \<union> {a\<sqinter>b |a b. a \<in> A \<and> b \<in> B})"
  2469   also have "\<dots> = \<Squnion>\<^bsub>fin\<^esub>({x\<sqinter>b |b. b \<in> B} \<union> {a\<sqinter>b |a b. a \<in> A \<and> b \<in> B})"
  2473     (is "_ = \<Squnion>?M")
  2470     (is "_ = \<Squnion>\<^bsub>fin\<^esub>?M")
  2474     using B insert
  2471     using B insert
  2475     by(simp add:Sup_def ACIf.fold1_Un2[OF ACIf_sup finB _ finAB ne])
  2472     by (simp add: Sup_fin_def ACIf.fold1_Un2[OF ACIf_sup finB _ finAB ne])
  2476   also have "?M = {a \<sqinter> b |a b. a \<in> insert x A \<and> b \<in> B}"
  2473   also have "?M = {a \<sqinter> b |a b. a \<in> insert x A \<and> b \<in> B}"
  2477     by blast
  2474     by blast
  2478   finally show ?case .
  2475   finally show ?case .
  2479 qed
  2476 qed
  2480 
  2477 
       
  2478 end
       
  2479 
       
  2480 context complete_lattice
       
  2481 begin
       
  2482 
  2481 text {*
  2483 text {*
  2482   Infimum and supremum in complete lattices may also
  2484   Coincidence on finite sets in complete lattices:
  2483   be characterized by @{const fold1}:
       
  2484 *}
  2485 *}
  2485 
  2486 
  2486 lemma (in complete_lattice) Inf_fold1:
  2487 lemma Inf_fin_Inf:
  2487   "finite A \<Longrightarrow>  A \<noteq> {} \<Longrightarrow> \<Sqinter>A = fold1 (op \<sqinter>) A"
  2488   "finite A \<Longrightarrow>  A \<noteq> {} \<Longrightarrow> \<Sqinter>\<^bsub>fin\<^esub>A = \<Sqinter>A"
  2488 by (induct A set: finite)
  2489 unfolding Inf_fin_def by (induct A set: finite)
  2489    (simp_all add: Inf_insert_simp ACIf.fold1_insert_idem [OF ACIf_inf])
  2490    (simp_all add: Inf_insert_simp ACIf.fold1_insert_idem [OF ACIf_inf])
  2490 
  2491 
  2491 lemma (in complete_lattice) Sup_fold1:
  2492 lemma Sup_fin_Sup:
  2492   "finite A \<Longrightarrow> A \<noteq> {} \<Longrightarrow> \<Squnion>A = fold1 (op \<squnion>) A"
  2493   "finite A \<Longrightarrow> A \<noteq> {} \<Longrightarrow> \<Squnion>\<^bsub>fin\<^esub>A = \<Squnion>A"
  2493 by (induct A set: finite)
  2494 unfolding Sup_fin_def by (induct A set: finite)
  2494    (simp_all add: Sup_insert_simp ACIf.fold1_insert_idem [OF ACIf_sup])
  2495    (simp_all add: Sup_insert_simp ACIf.fold1_insert_idem [OF ACIf_sup])
       
  2496 
       
  2497 end
  2495 
  2498 
  2496 
  2499 
  2497 subsubsection {* Fold1 in linear orders with @{const min} and @{const max} *}
  2500 subsubsection {* Fold1 in linear orders with @{const min} and @{const max} *}
  2498 
  2501 
  2499 text{*
  2502 text{*
  2500   As an application of @{text fold1} we define minimum
  2503   As an application of @{text fold1} we define minimum
  2501   and maximum in (not necessarily complete!) linear orders
  2504   and maximum in (not necessarily complete!) linear orders
  2502   over (non-empty) sets by means of @{text fold1}.
  2505   over (non-empty) sets by means of @{text fold1}.
  2503 *}
  2506 *}
  2504 
  2507 
  2505 locale Linorder = linorder -- {* we do not pollute the @{text linorder} class *}
  2508 context linorder
  2506 begin
  2509 begin
  2507 
  2510 
  2508 definition
  2511 definition
  2509   Min :: "'a set \<Rightarrow> 'a"
  2512   Min :: "'a set \<Rightarrow> 'a"
  2510 where
  2513 where
  2512 
  2515 
  2513 definition
  2516 definition
  2514   Max :: "'a set \<Rightarrow> 'a"
  2517   Max :: "'a set \<Rightarrow> 'a"
  2515 where
  2518 where
  2516   "Max = fold1 max"
  2519   "Max = fold1 max"
       
  2520 
       
  2521 end context linorder begin
  2517 
  2522 
  2518 text {* recall: @{term min} and @{term max} behave like @{const inf} and @{const sup} *}
  2523 text {* recall: @{term min} and @{term max} behave like @{const inf} and @{const sup} *}
  2519 
  2524 
  2520 lemma ACIf_min: "ACIf min"
  2525 lemma ACIf_min: "ACIf min"
  2521   by (rule lower_semilattice.ACIf_inf,
  2526   by (rule lower_semilattice.ACIf_inf,
  2646   \<Longrightarrow> finite N \<Longrightarrow> N \<noteq> {} \<Longrightarrow> h (Max N) = Max (h ` N)"
  2651   \<Longrightarrow> finite N \<Longrightarrow> N \<noteq> {} \<Longrightarrow> h (Max N) = Max (h ` N)"
  2647   by (simp add: Max_def ACIf.hom_fold1_commute [OF ACIf_max])
  2652   by (simp add: Max_def ACIf.hom_fold1_commute [OF ACIf_max])
  2648 
  2653 
  2649 end
  2654 end
  2650 
  2655 
  2651 locale Linorder_ab_semigroup_add = Linorder + pordered_ab_semigroup_add
  2656 class linordered_ab_semigroup_add = linorder + pordered_ab_semigroup_add
  2652 begin
  2657 begin
  2653 
  2658 
  2654 lemma add_Min_commute:
  2659 lemma add_Min_commute:
  2655   fixes k
  2660   fixes k
  2656   shows "finite N \<Longrightarrow> N \<noteq> {} \<Longrightarrow> k \<^loc>+ Min N = Min {k \<^loc>+ m | m. m \<in> N}"
  2661   shows "finite N \<Longrightarrow> N \<noteq> {} \<Longrightarrow> k \<^loc>+ Min N = Min {k \<^loc>+ m | m. m \<in> N}"
  2671   apply (blast intro: antisym less_imp_le add_left_mono)
  2676   apply (blast intro: antisym less_imp_le add_left_mono)
  2672   done
  2677   done
  2673 
  2678 
  2674 end
  2679 end
  2675 
  2680 
  2676 definition
       
  2677   Min :: "'a set \<Rightarrow> 'a\<Colon>linorder"
       
  2678 where
       
  2679   "Min = fold1 min"
       
  2680 
       
  2681 definition
       
  2682   Max :: "'a set \<Rightarrow> 'a\<Colon>linorder"
       
  2683 where
       
  2684   "Max = fold1 max"
       
  2685 
       
  2686 interpretation
       
  2687   Linorder ["op \<le> \<Colon> 'a\<Colon>linorder \<Rightarrow> 'a \<Rightarrow> bool" "op <"]
       
  2688 where
       
  2689   "Linorder.Min (op \<le> \<Colon> 'a\<Colon>linorder \<Rightarrow> 'a \<Rightarrow> bool) = Min"
       
  2690   and "Linorder.Max (op \<le> \<Colon> 'a\<Colon>linorder \<Rightarrow> 'a \<Rightarrow> bool) = Max"
       
  2691 proof -
       
  2692   show "Linorder (op \<le> \<Colon> 'a \<Rightarrow> 'a \<Rightarrow> bool) op <"
       
  2693   by (rule Linorder.intro, rule linorder_axioms)
       
  2694   then interpret Linorder: Linorder ["op \<le> \<Colon> 'a \<Rightarrow> 'a \<Rightarrow> bool" "op <"] .
       
  2695   show "Linorder.Min = Min" by (simp add: Min_def Linorder.Min_def ord_class.min)
       
  2696   show "Linorder.Max = Max" by (simp add: Max_def Linorder.Max_def ord_class.max)
       
  2697 qed
       
  2698 
       
  2699 interpretation
       
  2700   Linorder_ab_semigroup_add ["op \<le> \<Colon> 'a\<Colon>{linorder, pordered_ab_semigroup_add} \<Rightarrow> 'a \<Rightarrow> bool" "op <" "op +"]
       
  2701 proof -
       
  2702   show "Linorder_ab_semigroup_add (op \<le> \<Colon> 'a \<Rightarrow> 'a \<Rightarrow> bool) (op <) (op +)"
       
  2703   by (rule Linorder_ab_semigroup_add.intro,
       
  2704     rule Linorder.intro, rule linorder_axioms, rule pordered_ab_semigroup_add_axioms)
       
  2705 qed
       
  2706 
       
  2707 
  2681 
  2708 subsection {* Class @{text finite} *}
  2682 subsection {* Class @{text finite} *}
  2709 
  2683 
  2710 setup {* Sign.add_path "finite" *} -- {*FIXME: name tweaking*}
  2684 setup {* Sign.add_path "finite" *} -- {*FIXME: name tweaking*}
  2711 class finite (attach UNIV) = type +
  2685 class finite (attach UNIV) = type +