175 with A show "A \<subseteq> F" by (simp add: subset_insert_iff) |
175 with A show "A \<subseteq> F" by (simp add: subset_insert_iff) |
176 qed |
176 qed |
177 qed |
177 qed |
178 qed |
178 qed |
179 |
179 |
180 lemma finite_Collect_subset: "finite A \<Longrightarrow> finite{x \<in> A. P x}" |
180 lemma finite_Collect_subset[simp]: "finite A \<Longrightarrow> finite{x \<in> A. P x}" |
181 using finite_subset[of "{x \<in> A. P x}" "A"] by blast |
181 using finite_subset[of "{x \<in> A. P x}" "A"] by blast |
182 |
182 |
183 lemma finite_Un [iff]: "finite (F Un G) = (finite F & finite G)" |
183 lemma finite_Un [iff]: "finite (F Un G) = (finite F & finite G)" |
184 by (blast intro: finite_subset [of _ "X Un Y", standard] finite_UnI) |
184 by (blast intro: finite_subset [of _ "X Un Y", standard] finite_UnI) |
185 |
185 |
2106 shows "fold1 f A \<sqsubseteq> x = (\<exists>a\<in>A. a \<sqsubseteq> x)" |
2106 shows "fold1 f A \<sqsubseteq> x = (\<exists>a\<in>A. a \<sqsubseteq> x)" |
2107 using A |
2107 using A |
2108 by(induct rule:finite_ne_induct)(simp_all add:above_f_conv) |
2108 by(induct rule:finite_ne_induct)(simp_all add:above_f_conv) |
2109 |
2109 |
2110 |
2110 |
|
2111 lemma (in ACIfSLlin) fold1_antimono: |
|
2112 assumes "A \<noteq> {}" and "A \<subseteq> B" and "finite B" |
|
2113 shows "fold1 f B \<sqsubseteq> fold1 f A" |
|
2114 proof(cases) |
|
2115 assume "A = B" thus ?thesis by simp |
|
2116 next |
|
2117 assume "A \<noteq> B" |
|
2118 have B: "B = A \<union> (B-A)" using `A \<subseteq> B` by blast |
|
2119 have "fold1 f B = fold1 f (A \<union> (B-A))" by(subst B)(rule refl) |
|
2120 also have "\<dots> = f (fold1 f A) (fold1 f (B-A))" |
|
2121 proof - |
|
2122 have "finite A" by(rule finite_subset[OF `A \<subseteq> B` `finite B`]) |
|
2123 moreover have "finite(B-A)" by(blast intro:finite_Diff prems) |
|
2124 moreover have "(B-A) \<noteq> {}" using prems by blast |
|
2125 moreover have "A Int (B-A) = {}" using prems by blast |
|
2126 ultimately show ?thesis using `A \<noteq> {}` by(rule_tac fold1_Un) |
|
2127 qed |
|
2128 also have "\<dots> \<sqsubseteq> fold1 f A" by(simp add: above_f_conv) |
|
2129 finally show ?thesis . |
|
2130 qed |
|
2131 |
|
2132 |
2111 subsubsection{* Lattices *} |
2133 subsubsection{* Lattices *} |
2112 |
2134 |
2113 locale Lattice = lattice + |
2135 locale Lattice = lattice + |
2114 fixes Inf :: "'a set \<Rightarrow> 'a" ("\<Sqinter>_" [900] 900) |
2136 fixes Inf :: "'a set \<Rightarrow> 'a" ("\<Sqinter>_" [900] 900) |
2115 and Sup :: "'a set \<Rightarrow> 'a" ("\<Squnion>_" [900] 900) |
2137 and Sup :: "'a set \<Rightarrow> 'a" ("\<Squnion>_" [900] 900) |
2183 lemma (in Lattice) inf_Sup_absorb[simp]: |
2205 lemma (in Lattice) inf_Sup_absorb[simp]: |
2184 "\<lbrakk> finite A; A \<noteq> {}; a \<in> A \<rbrakk> \<Longrightarrow> (a \<sqinter> \<Squnion>A) = a" |
2206 "\<lbrakk> finite A; A \<noteq> {}; a \<in> A \<rbrakk> \<Longrightarrow> (a \<sqinter> \<Squnion>A) = a" |
2185 by(simp add:Sup_def inf_absorb ACIfSL.fold1_belowI[OF ACIfSL_sup]) |
2207 by(simp add:Sup_def inf_absorb ACIfSL.fold1_belowI[OF ACIfSL_sup]) |
2186 |
2208 |
2187 |
2209 |
|
2210 lemma (in ACIf) hom_fold1_commute: |
|
2211 assumes hom: "!!x y. h(f x y) = f (h x) (h y)" |
|
2212 and N: "finite N" "N \<noteq> {}" shows "h(fold1 f N) = fold1 f (h ` N)" |
|
2213 using N proof (induct rule: finite_ne_induct) |
|
2214 case singleton thus ?case by simp |
|
2215 next |
|
2216 case (insert n N) |
|
2217 have "h(fold1 f (insert n N)) = h(f n (fold1 f N))" using insert by(simp) |
|
2218 also have "\<dots> = f (h n) (h(fold1 f N))" by(rule hom) |
|
2219 also have "h(fold1 f N) = fold1 f (h ` N)" by(rule insert) |
|
2220 also have "f (h n) \<dots> = fold1 f (insert (h n) (h ` N))" |
|
2221 using insert by(simp) |
|
2222 also have "insert (h n) (h ` N) = h ` insert n N" by simp |
|
2223 finally show ?case . |
|
2224 qed |
|
2225 |
2188 lemma (in Distrib_Lattice) sup_Inf1_distrib: |
2226 lemma (in Distrib_Lattice) sup_Inf1_distrib: |
2189 assumes A: "finite A" "A \<noteq> {}" |
2227 "finite A \<Longrightarrow> A \<noteq> {} \<Longrightarrow> (x \<squnion> \<Sqinter>A) = \<Sqinter>{x \<squnion> a|a. a \<in> A}" |
2190 shows "(x \<squnion> \<Sqinter>A) = \<Sqinter>{x \<squnion> a|a. a \<in> A}" |
2228 apply(simp add:Inf_def image_def |
2191 using A |
2229 ACIf.hom_fold1_commute[OF ACIf_inf, where h="sup x", OF sup_inf_distrib1]) |
2192 proof (induct rule: finite_ne_induct) |
2230 apply(rule arg_cong, blast) |
2193 case singleton thus ?case by(simp add:Inf_def) |
2231 done |
2194 next |
2232 |
2195 case (insert y A) |
|
2196 have fin: "finite {x \<squnion> a |a. a \<in> A}" |
|
2197 by(fast intro: finite_surj[where f = "%a. x \<squnion> a", OF insert(1)]) |
|
2198 have "x \<squnion> \<Sqinter> (insert y A) = x \<squnion> (y \<sqinter> \<Sqinter> A)" |
|
2199 using insert by(simp add:ACf.fold1_insert_def[OF ACf_inf Inf_def]) |
|
2200 also have "\<dots> = (x \<squnion> y) \<sqinter> (x \<squnion> \<Sqinter> A)" by(rule sup_inf_distrib1) |
|
2201 also have "x \<squnion> \<Sqinter> A = \<Sqinter>{x \<squnion> a|a. a \<in> A}" using insert by simp |
|
2202 also have "(x \<squnion> y) \<sqinter> \<dots> = \<Sqinter> (insert (x \<squnion> y) {x \<squnion> a |a. a \<in> A})" |
|
2203 using insert by(simp add:ACIf.fold1_insert_idem_def[OF ACIf_inf Inf_def fin]) |
|
2204 also have "insert (x\<squnion>y) {x\<squnion>a |a. a \<in> A} = {x\<squnion>a |a. a \<in> insert y A}" |
|
2205 by blast |
|
2206 finally show ?case . |
|
2207 qed |
|
2208 |
2233 |
2209 lemma (in Distrib_Lattice) sup_Inf2_distrib: |
2234 lemma (in Distrib_Lattice) sup_Inf2_distrib: |
2210 assumes A: "finite A" "A \<noteq> {}" and B: "finite B" "B \<noteq> {}" |
2235 assumes A: "finite A" "A \<noteq> {}" and B: "finite B" "B \<noteq> {}" |
2211 shows "(\<Sqinter>A \<squnion> \<Sqinter>B) = \<Sqinter>{a \<squnion> b|a b. a \<in> A \<and> b \<in> B}" |
2236 shows "(\<Sqinter>A \<squnion> \<Sqinter>B) = \<Sqinter>{a \<squnion> b|a b. a \<in> A \<and> b \<in> B}" |
2212 using A |
2237 using A |
2237 by blast |
2262 by blast |
2238 finally show ?case . |
2263 finally show ?case . |
2239 qed |
2264 qed |
2240 |
2265 |
2241 |
2266 |
|
2267 lemma (in Distrib_Lattice) inf_Sup1_distrib: |
|
2268 "finite A \<Longrightarrow> A \<noteq> {} \<Longrightarrow> (x \<sqinter> \<Squnion>A) = \<Squnion>{x \<sqinter> a|a. a \<in> A}" |
|
2269 apply(simp add:Sup_def image_def |
|
2270 ACIf.hom_fold1_commute[OF ACIf_sup, where h="inf x", OF inf_sup_distrib1]) |
|
2271 apply(rule arg_cong, blast) |
|
2272 done |
|
2273 |
|
2274 |
|
2275 lemma (in Distrib_Lattice) inf_Sup2_distrib: |
|
2276 assumes A: "finite A" "A \<noteq> {}" and B: "finite B" "B \<noteq> {}" |
|
2277 shows "(\<Squnion>A \<sqinter> \<Squnion>B) = \<Squnion>{a \<sqinter> b|a b. a \<in> A \<and> b \<in> B}" |
|
2278 using A |
|
2279 proof (induct rule: finite_ne_induct) |
|
2280 case singleton thus ?case |
|
2281 by(simp add: inf_Sup1_distrib[OF B] fold1_singleton_def[OF Sup_def]) |
|
2282 next |
|
2283 case (insert x A) |
|
2284 have finB: "finite {x \<sqinter> b |b. b \<in> B}" |
|
2285 by(fast intro: finite_surj[where f = "%b. x \<sqinter> b", OF B(1)]) |
|
2286 have finAB: "finite {a \<sqinter> b |a b. a \<in> A \<and> b \<in> B}" |
|
2287 proof - |
|
2288 have "{a \<sqinter> b |a b. a \<in> A \<and> b \<in> B} = (UN a:A. UN b:B. {a \<sqinter> b})" |
|
2289 by blast |
|
2290 thus ?thesis by(simp add: insert(1) B(1)) |
|
2291 qed |
|
2292 have ne: "{a \<sqinter> b |a b. a \<in> A \<and> b \<in> B} \<noteq> {}" using insert B by blast |
|
2293 have "\<Squnion>(insert x A) \<sqinter> \<Squnion>B = (x \<squnion> \<Squnion>A) \<sqinter> \<Squnion>B" |
|
2294 using insert by(simp add:ACIf.fold1_insert_idem_def[OF ACIf_sup Sup_def]) |
|
2295 also have "\<dots> = (x \<sqinter> \<Squnion>B) \<squnion> (\<Squnion>A \<sqinter> \<Squnion>B)" by(rule inf_sup_distrib2) |
|
2296 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}" |
|
2297 using insert by(simp add:inf_Sup1_distrib[OF B]) |
|
2298 also have "\<dots> = \<Squnion>({x\<sqinter>b |b. b \<in> B} \<union> {a\<sqinter>b |a b. a \<in> A \<and> b \<in> B})" |
|
2299 (is "_ = \<Squnion>?M") |
|
2300 using B insert |
|
2301 by(simp add:Sup_def ACIf.fold1_Un2[OF ACIf_sup finB _ finAB ne]) |
|
2302 also have "?M = {a \<sqinter> b |a b. a \<in> insert x A \<and> b \<in> B}" |
|
2303 by blast |
|
2304 finally show ?case . |
|
2305 qed |
|
2306 |
|
2307 |
2242 subsection{*Min and Max*} |
2308 subsection{*Min and Max*} |
2243 |
2309 |
2244 text{* As an application of @{text fold1} we define the minimal and |
2310 text{* As an application of @{text fold1} we define the minimal and |
2245 maximal element of a (non-empty) set over a linear order. *} |
2311 maximal element of a (non-empty) set over a linear order. *} |
2246 |
2312 |
2336 lemma Max_in [simp]: |
2402 lemma Max_in [simp]: |
2337 shows "finite A \<Longrightarrow> A \<noteq> {} \<Longrightarrow> Max A \<in> A" |
2403 shows "finite A \<Longrightarrow> A \<noteq> {} \<Longrightarrow> Max A \<in> A" |
2338 using max.fold1_in |
2404 using max.fold1_in |
2339 by(fastsimp simp: Max_def max_def) |
2405 by(fastsimp simp: Max_def max_def) |
2340 |
2406 |
|
2407 lemma Min_antimono: "\<lbrakk> M \<subseteq> N; M \<noteq> {}; finite N \<rbrakk> \<Longrightarrow> Min N \<le> Min M" |
|
2408 by(simp add:Finite_Set.Min_def min.fold1_antimono) |
|
2409 |
|
2410 lemma Max_mono: "\<lbrakk> M \<subseteq> N; M \<noteq> {}; finite N \<rbrakk> \<Longrightarrow> Max M \<le> Max N" |
|
2411 by(simp add:Max_def max.fold1_antimono) |
|
2412 |
2341 lemma Min_le [simp]: "\<lbrakk> finite A; A \<noteq> {}; x \<in> A \<rbrakk> \<Longrightarrow> Min A \<le> x" |
2413 lemma Min_le [simp]: "\<lbrakk> finite A; A \<noteq> {}; x \<in> A \<rbrakk> \<Longrightarrow> Min A \<le> x" |
2342 by(simp add: Min_def min.fold1_belowI) |
2414 by(simp add: Min_def min.fold1_belowI) |
2343 |
2415 |
2344 lemma Max_ge [simp]: "\<lbrakk> finite A; A \<noteq> {}; x \<in> A \<rbrakk> \<Longrightarrow> x \<le> Max A" |
2416 lemma Max_ge [simp]: "\<lbrakk> finite A; A \<noteq> {}; x \<in> A \<rbrakk> \<Longrightarrow> x \<le> Max A" |
2345 by(simp add: Max_def max.fold1_belowI) |
2417 by(simp add: Max_def max.fold1_belowI) |
2357 by(simp add: Min_def min.fold1_below_iff) |
2429 by(simp add: Min_def min.fold1_below_iff) |
2358 |
2430 |
2359 lemma Max_ge_iff: |
2431 lemma Max_ge_iff: |
2360 "\<lbrakk> finite A; A \<noteq> {} \<rbrakk> \<Longrightarrow> (x \<le> Max A) = (\<exists>a\<in>A. x \<le> a)" |
2432 "\<lbrakk> finite A; A \<noteq> {} \<rbrakk> \<Longrightarrow> (x \<le> Max A) = (\<exists>a\<in>A. x \<le> a)" |
2361 by(simp add: Max_def max.fold1_below_iff) |
2433 by(simp add: Max_def max.fold1_below_iff) |
|
2434 |
|
2435 lemma Min_Un: "\<lbrakk>finite A; A \<noteq> {}; finite B; B \<noteq> {}\<rbrakk> |
|
2436 \<Longrightarrow> Min (A \<union> B) = min (Min A) (Min B)" |
|
2437 by(simp add:Min_def min.f.fold1_Un2) |
|
2438 |
|
2439 lemma Max_Un: "\<lbrakk>finite A; A \<noteq> {}; finite B; B \<noteq> {}\<rbrakk> |
|
2440 \<Longrightarrow> Max (A \<union> B) = max (Max A) (Max B)" |
|
2441 by(simp add:Max_def max.f.fold1_Un2) |
|
2442 |
|
2443 |
|
2444 lemma hom_Min_commute: |
|
2445 "(!!x y::'a::linorder. h(min x y) = min (h x) (h y::'a)) |
|
2446 \<Longrightarrow> finite N \<Longrightarrow> N \<noteq> {} \<Longrightarrow> h(Min N) = Min(h ` N)" |
|
2447 by(simp add:Finite_Set.Min_def min.hom_fold1_commute) |
|
2448 |
|
2449 lemma hom_Max_commute: |
|
2450 "(!!x y::'a::linorder. h(max x y) = max (h x) (h y::'a)) |
|
2451 \<Longrightarrow> finite N \<Longrightarrow> N \<noteq> {} \<Longrightarrow> h(Max N) = Max(h ` N)" |
|
2452 by(simp add:Max_def max.hom_fold1_commute) |
|
2453 |
|
2454 |
|
2455 lemma add_Min_commute: fixes k::"'a::{pordered_ab_semigroup_add,linorder}" |
|
2456 shows "finite N \<Longrightarrow> N \<noteq> {} \<Longrightarrow> k + Min N = Min {k+m|m. m \<in> N}" |
|
2457 apply(subgoal_tac "!!x y. k + min x y = min (k + x) (k + y)") |
|
2458 using hom_Min_commute[of "op + k" N] |
|
2459 apply simp apply(rule arg_cong[where f = Min]) apply blast |
|
2460 apply(simp add:min_def linorder_not_le) |
|
2461 apply(blast intro:order.antisym order_less_imp_le add_left_mono) |
|
2462 done |
|
2463 |
|
2464 lemma add_Max_commute: fixes k::"'a::{pordered_ab_semigroup_add,linorder}" |
|
2465 shows "finite N \<Longrightarrow> N \<noteq> {} \<Longrightarrow> k + Max N = Max {k+m|m. m \<in> N}" |
|
2466 apply(subgoal_tac "!!x y. k + max x y = max (k + x) (k + y)") |
|
2467 using hom_Max_commute[of "op + k" N] |
|
2468 apply simp apply(rule arg_cong[where f = Max]) apply blast |
|
2469 apply(simp add:max_def linorder_not_le) |
|
2470 apply(blast intro:order.antisym order_less_imp_le add_left_mono) |
|
2471 done |
|
2472 |
|
2473 |
2362 |
2474 |
2363 subsection {* Properties of axclass @{text finite} *} |
2475 subsection {* Properties of axclass @{text finite} *} |
2364 |
2476 |
2365 text{* Many of these are by Brian Huffman. *} |
2477 text{* Many of these are by Brian Huffman. *} |
2366 |
2478 |