# HG changeset patch # User ballarin # Date 1488485762 -3600 # Node ID 30d0b2f1df768f398c6a36da855205aa866a99a9 # Parent b47ba1778e44f1a67fcdfec6f35cf3c1e3c090ba Knaster-Tarski fixed point theorem and Galois Connections. diff -r b47ba1778e44 -r 30d0b2f1df76 CONTRIBUTORS --- a/CONTRIBUTORS Fri Mar 03 23:21:24 2017 +0100 +++ b/CONTRIBUTORS Thu Mar 02 21:16:02 2017 +0100 @@ -6,6 +6,9 @@ Contributions to this Isabelle version -------------------------------------- +* March 2017: Alasdair Armstrong and Simon Foster, University of York + Fixed-point theory and Galois Connections in HOL-Algebra. + * February 2017: Florian Haftmann, TUM Statically embedded computations implemented by generated code. diff -r b47ba1778e44 -r 30d0b2f1df76 NEWS --- a/NEWS Fri Mar 03 23:21:24 2017 +0100 +++ b/NEWS Thu Mar 02 21:16:02 2017 +0100 @@ -108,6 +108,9 @@ with type class annotations. As a result, the tactic that derives it no longer fails on nested datatypes. Slight INCOMPATIBILITY. +* Session HOL-Algebra extended by additional lattice theory: the +Knaster-Tarski fixed point theorem and Galois Connections. + * Session HOL-Analysis: more material involving arcs, paths, covering spaces, innessential maps, retracts. Major results include the Jordan Curve Theorem and the Great Picard Theorem. diff -r b47ba1778e44 -r 30d0b2f1df76 src/HOL/Algebra/Complete_Lattice.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Algebra/Complete_Lattice.thy Thu Mar 02 21:16:02 2017 +0100 @@ -0,0 +1,1191 @@ +(* Title: HOL/Algebra/Complete_Lattice.thy + Author: Clemens Ballarin, started 7 November 2003 + Copyright: Clemens Ballarin + +Most congruence rules by Stephan Hohe. +With additional contributions from Alasdair Armstrong and Simon Foster. +*) + +theory Complete_Lattice +imports Lattice +begin + +section \Complete Lattices\ + +locale weak_complete_lattice = weak_partial_order + + assumes sup_exists: + "[| A \ carrier L |] ==> EX s. least L s (Upper L A)" + and inf_exists: + "[| A \ carrier L |] ==> EX i. greatest L i (Lower L A)" + +sublocale weak_complete_lattice \ weak_lattice +proof + fix x y + assume a: "x \ carrier L" "y \ carrier L" + thus "\s. is_lub L s {x, y}" + by (rule_tac sup_exists[of "{x, y}"], auto) + from a show "\s. is_glb L s {x, y}" + by (rule_tac inf_exists[of "{x, y}"], auto) +qed + +text \Introduction rule: the usual definition of complete lattice\ + +lemma (in weak_partial_order) weak_complete_latticeI: + assumes sup_exists: + "!!A. [| A \ carrier L |] ==> EX s. least L s (Upper L A)" + and inf_exists: + "!!A. [| A \ carrier L |] ==> EX i. greatest L i (Lower L A)" + shows "weak_complete_lattice L" + by standard (auto intro: sup_exists inf_exists) + +lemma (in weak_complete_lattice) dual_weak_complete_lattice: + "weak_complete_lattice (inv_gorder L)" +proof - + interpret dual: weak_lattice "inv_gorder L" + by (metis dual_weak_lattice) + + show ?thesis + apply (unfold_locales) + apply (simp_all add:inf_exists sup_exists) + done +qed + +lemma (in weak_complete_lattice) supI: + "[| !!l. least L l (Upper L A) ==> P l; A \ carrier L |] + ==> P (\A)" +proof (unfold sup_def) + assume L: "A \ carrier L" + and P: "!!l. least L l (Upper L A) ==> P l" + with sup_exists obtain s where "least L s (Upper L A)" by blast + with L show "P (SOME l. least L l (Upper L A))" + by (fast intro: someI2 weak_least_unique P) +qed + +lemma (in weak_complete_lattice) sup_closed [simp]: + "A \ carrier L ==> \A \ carrier L" + by (rule supI) simp_all + +lemma (in weak_complete_lattice) sup_cong: + assumes "A \ carrier L" "B \ carrier L" "A {.=} B" + shows "\ A .= \ B" +proof - + have "\ x. is_lub L x A \ is_lub L x B" + by (rule least_Upper_cong_r, simp_all add: assms) + moreover have "\ B \ carrier L" + by (simp add: assms(2)) + ultimately show ?thesis + by (simp add: sup_def) +qed + +sublocale weak_complete_lattice \ weak_bounded_lattice + apply (unfold_locales) + apply (metis Upper_empty empty_subsetI sup_exists) + apply (metis Lower_empty empty_subsetI inf_exists) +done + +lemma (in weak_complete_lattice) infI: + "[| !!i. greatest L i (Lower L A) ==> P i; A \ carrier L |] + ==> P (\A)" +proof (unfold inf_def) + assume L: "A \ carrier L" + and P: "!!l. greatest L l (Lower L A) ==> P l" + with inf_exists obtain s where "greatest L s (Lower L A)" by blast + with L show "P (SOME l. greatest L l (Lower L A))" + by (fast intro: someI2 weak_greatest_unique P) +qed + +lemma (in weak_complete_lattice) inf_closed [simp]: + "A \ carrier L ==> \A \ carrier L" + by (rule infI) simp_all + +lemma (in weak_complete_lattice) inf_cong: + assumes "A \ carrier L" "B \ carrier L" "A {.=} B" + shows "\ A .= \ B" +proof - + have "\ x. is_glb L x A \ is_glb L x B" + by (rule greatest_Lower_cong_r, simp_all add: assms) + moreover have "\ B \ carrier L" + by (simp add: assms(2)) + ultimately show ?thesis + by (simp add: inf_def) +qed + +theorem (in weak_partial_order) weak_complete_lattice_criterion1: + assumes top_exists: "EX g. greatest L g (carrier L)" + and inf_exists: + "!!A. [| A \ carrier L; A ~= {} |] ==> EX i. greatest L i (Lower L A)" + shows "weak_complete_lattice L" +proof (rule weak_complete_latticeI) + from top_exists obtain top where top: "greatest L top (carrier L)" .. + fix A + assume L: "A \ carrier L" + let ?B = "Upper L A" + from L top have "top \ ?B" by (fast intro!: Upper_memI intro: greatest_le) + then have B_non_empty: "?B ~= {}" by fast + have B_L: "?B \ carrier L" by simp + from inf_exists [OF B_L B_non_empty] + obtain b where b_inf_B: "greatest L b (Lower L ?B)" .. + have "least L b (Upper L A)" +apply (rule least_UpperI) + apply (rule greatest_le [where A = "Lower L ?B"]) + apply (rule b_inf_B) + apply (rule Lower_memI) + apply (erule Upper_memD [THEN conjunct1]) + apply assumption + apply (rule L) + apply (fast intro: L [THEN subsetD]) + apply (erule greatest_Lower_below [OF b_inf_B]) + apply simp + apply (rule L) +apply (rule greatest_closed [OF b_inf_B]) +done + then show "EX s. least L s (Upper L A)" .. +next + fix A + assume L: "A \ carrier L" + show "EX i. greatest L i (Lower L A)" + proof (cases "A = {}") + case True then show ?thesis + by (simp add: top_exists) + next + case False with L show ?thesis + by (rule inf_exists) + qed +qed + + +text \Supremum\ + +declare (in partial_order) weak_sup_of_singleton [simp del] + +lemma (in partial_order) sup_of_singleton [simp]: + "x \ carrier L ==> \{x} = x" + using weak_sup_of_singleton unfolding eq_is_equal . + +lemma (in upper_semilattice) join_assoc_lemma: + assumes L: "x \ carrier L" "y \ carrier L" "z \ carrier L" + shows "x \ (y \ z) = \{x, y, z}" + using weak_join_assoc_lemma L unfolding eq_is_equal . + +lemma (in upper_semilattice) join_assoc: + assumes L: "x \ carrier L" "y \ carrier L" "z \ carrier L" + shows "(x \ y) \ z = x \ (y \ z)" + using weak_join_assoc L unfolding eq_is_equal . + + +text \Infimum\ + +declare (in partial_order) weak_inf_of_singleton [simp del] + +lemma (in partial_order) inf_of_singleton [simp]: + "x \ carrier L ==> \{x} = x" + using weak_inf_of_singleton unfolding eq_is_equal . + +text \Condition on \A\: infimum exists.\ + +lemma (in lower_semilattice) meet_assoc_lemma: + assumes L: "x \ carrier L" "y \ carrier L" "z \ carrier L" + shows "x \ (y \ z) = \{x, y, z}" + using weak_meet_assoc_lemma L unfolding eq_is_equal . + +lemma (in lower_semilattice) meet_assoc: + assumes L: "x \ carrier L" "y \ carrier L" "z \ carrier L" + shows "(x \ y) \ z = x \ (y \ z)" + using weak_meet_assoc L unfolding eq_is_equal . + + +subsection \Infimum Laws\ + +context weak_complete_lattice +begin + +lemma inf_glb: + assumes "A \ carrier L" + shows "greatest L (\A) (Lower L A)" +proof - + obtain i where "greatest L i (Lower L A)" + by (metis assms inf_exists) + + thus ?thesis + apply (simp add: inf_def) + apply (rule someI2[of _ "i"]) + apply (auto) + done +qed + +lemma inf_lower: + assumes "A \ carrier L" "x \ A" + shows "\A \ x" + by (metis assms greatest_Lower_below inf_glb) + +lemma inf_greatest: + assumes "A \ carrier L" "z \ carrier L" + "(\x. x \ A \ z \ x)" + shows "z \ \A" + by (metis Lower_memI assms greatest_le inf_glb) + +lemma weak_inf_empty [simp]: "\{} .= \" + by (metis Lower_empty empty_subsetI inf_glb top_greatest weak_greatest_unique) + +lemma weak_inf_carrier [simp]: "\carrier L .= \" + by (metis bottom_weak_eq inf_closed inf_lower subset_refl) + +lemma weak_inf_insert [simp]: + "\ a \ carrier L; A \ carrier L \ \ \insert a A .= a \ \A" + apply (rule weak_le_antisym) + apply (force intro: meet_le inf_greatest inf_lower inf_closed) + apply (rule inf_greatest) + apply (force) + apply (force intro: inf_closed) + apply (auto) + apply (metis inf_closed meet_left) + apply (force intro: le_trans inf_closed meet_right meet_left inf_lower) +done + + +subsection \Supremum Laws\ + +lemma sup_lub: + assumes "A \ carrier L" + shows "least L (\A) (Upper L A)" + by (metis Upper_is_closed assms least_closed least_cong supI sup_closed sup_exists weak_least_unique) + +lemma sup_upper: + assumes "A \ carrier L" "x \ A" + shows "x \ \A" + by (metis assms least_Upper_above supI) + +lemma sup_least: + assumes "A \ carrier L" "z \ carrier L" + "(\x. x \ A \ x \ z)" + shows "\A \ z" + by (metis Upper_memI assms least_le sup_lub) + +lemma weak_sup_empty [simp]: "\{} .= \" + by (metis Upper_empty bottom_least empty_subsetI sup_lub weak_least_unique) + +lemma weak_sup_carrier [simp]: "\carrier L .= \" + by (metis Lower_closed Lower_empty sup_closed sup_upper top_closed top_higher weak_le_antisym) + +lemma weak_sup_insert [simp]: + "\ a \ carrier L; A \ carrier L \ \ \insert a A .= a \ \A" + apply (rule weak_le_antisym) + apply (rule sup_least) + apply (auto) + apply (metis join_left sup_closed) + apply (rule le_trans) defer + apply (rule join_right) + apply (auto) + apply (rule join_le) + apply (auto intro: sup_upper sup_least sup_closed) +done + +end + + +subsection \Fixed points of a lattice\ + +definition "fps L f = {x \ carrier L. f x .=\<^bsub>L\<^esub> x}" + +abbreviation "fpl L f \ L\carrier := fps L f\" + +lemma (in weak_partial_order) + use_fps: "x \ fps L f \ f x .= x" + by (simp add: fps_def) + +lemma fps_carrier [simp]: + "fps L f \ carrier L" + by (auto simp add: fps_def) + +lemma (in weak_complete_lattice) fps_sup_image: + assumes "f \ carrier L \ carrier L" "A \ fps L f" + shows "\ (f ` A) .= \ A" +proof - + from assms(2) have AL: "A \ carrier L" + by (auto simp add: fps_def) + + show ?thesis + proof (rule sup_cong, simp_all add: AL) + from assms(1) AL show "f ` A \ carrier L" + by (auto) + from assms(2) show "f ` A {.=} A" + apply (auto simp add: fps_def) + apply (rule set_eqI2) + apply blast + apply (rename_tac b) + apply (rule_tac x="f b" in bexI) + apply (metis (mono_tags, lifting) Ball_Collect assms(1) Pi_iff local.sym) + apply (auto) + done + qed +qed + +lemma (in weak_complete_lattice) fps_idem: + "\ f \ carrier L \ carrier L; Idem f \ \ fps L f {.=} f ` carrier L" + apply (rule set_eqI2) + apply (auto simp add: idempotent_def fps_def) + apply (metis Pi_iff local.sym) + apply force +done + +context weak_complete_lattice +begin + +lemma weak_sup_pre_fixed_point: + assumes "f \ carrier L \ carrier L" "isotone L L f" "A \ fps L f" + shows "(\\<^bsub>L\<^esub> A) \\<^bsub>L\<^esub> f (\\<^bsub>L\<^esub> A)" +proof (rule sup_least) + from assms(3) show AL: "A \ carrier L" + by (auto simp add: fps_def) + thus fA: "f (\A) \ carrier L" + by (simp add: assms funcset_carrier[of f L L]) + fix x + assume xA: "x \ A" + hence "x \ fps L f" + using assms subsetCE by blast + hence "f x .=\<^bsub>L\<^esub> x" + by (auto simp add: fps_def) + moreover have "f x \\<^bsub>L\<^esub> f (\\<^bsub>L\<^esub>A)" + by (meson AL assms(2) subsetCE sup_closed sup_upper use_iso1 xA) + ultimately show "x \\<^bsub>L\<^esub> f (\\<^bsub>L\<^esub>A)" + by (meson AL fA assms(1) funcset_carrier le_cong local.refl subsetCE xA) +qed + +lemma weak_sup_post_fixed_point: + assumes "f \ carrier L \ carrier L" "isotone L L f" "A \ fps L f" + shows "f (\\<^bsub>L\<^esub> A) \\<^bsub>L\<^esub> (\\<^bsub>L\<^esub> A)" +proof (rule inf_greatest) + from assms(3) show AL: "A \ carrier L" + by (auto simp add: fps_def) + thus fA: "f (\A) \ carrier L" + by (simp add: assms funcset_carrier[of f L L]) + fix x + assume xA: "x \ A" + hence "x \ fps L f" + using assms subsetCE by blast + hence "f x .=\<^bsub>L\<^esub> x" + by (auto simp add: fps_def) + moreover have "f (\\<^bsub>L\<^esub>A) \\<^bsub>L\<^esub> f x" + by (meson AL assms(2) inf_closed inf_lower subsetCE use_iso1 xA) + ultimately show "f (\\<^bsub>L\<^esub>A) \\<^bsub>L\<^esub> x" + by (meson AL assms(1) fA funcset_carrier le_cong_r subsetCE xA) +qed + + +subsubsection \Least fixed points\ + +lemma LFP_closed [intro, simp]: + "\ f \ carrier L" + by (metis (lifting) LFP_def inf_closed mem_Collect_eq subsetI) + +lemma LFP_lowerbound: + assumes "x \ carrier L" "f x \ x" + shows "\ f \ x" + by (auto intro:inf_lower assms simp add:LFP_def) + +lemma LFP_greatest: + assumes "x \ carrier L" + "(\u. \ u \ carrier L; f u \ u \ \ x \ u)" + shows "x \ \ f" + by (auto simp add:LFP_def intro:inf_greatest assms) + +lemma LFP_lemma2: + assumes "Mono f" "f \ carrier L \ carrier L" + shows "f (\ f) \ \ f" + using assms + apply (auto simp add:Pi_def) + apply (rule LFP_greatest) + apply (metis LFP_closed) + apply (metis LFP_closed LFP_lowerbound le_trans use_iso1) +done + +lemma LFP_lemma3: + assumes "Mono f" "f \ carrier L \ carrier L" + shows "\ f \ f (\ f)" + using assms + apply (auto simp add:Pi_def) + apply (metis LFP_closed LFP_lemma2 LFP_lowerbound assms(2) use_iso2) +done + +lemma LFP_weak_unfold: + "\ Mono f; f \ carrier L \ carrier L \ \ \ f .= f (\ f)" + by (auto intro: LFP_lemma2 LFP_lemma3 funcset_mem) + +lemma LFP_fixed_point [intro]: + assumes "Mono f" "f \ carrier L \ carrier L" + shows "\ f \ fps L f" +proof - + have "f (\ f) \ carrier L" + using assms(2) by blast + with assms show ?thesis + by (simp add: LFP_weak_unfold fps_def local.sym) +qed + +lemma LFP_least_fixed_point: + assumes "Mono f" "f \ carrier L \ carrier L" "x \ fps L f" + shows "\ f \ x" + using assms by (force intro: LFP_lowerbound simp add: fps_def) + +lemma LFP_idem: + assumes "f \ carrier L \ carrier L" "Mono f" "Idem f" + shows "\ f .= (f \)" +proof (rule weak_le_antisym) + from assms(1) show fb: "f \ \ carrier L" + by (rule funcset_mem, simp) + from assms show mf: "\ f \ carrier L" + by blast + show "\ f \ f \" + proof - + have "f (f \) .= f \" + by (auto simp add: fps_def fb assms(3) idempotent) + moreover have "f (f \) \ carrier L" + by (rule funcset_mem[of f "carrier L"], simp_all add: assms fb) + ultimately show ?thesis + by (auto intro: LFP_lowerbound simp add: fb) + qed + show "f \ \ \ f" + proof - + have "f \ \ f (\ f)" + by (auto intro: use_iso1[of _ f] simp add: assms) + moreover have "... .= \ f" + using assms(1) assms(2) fps_def by force + moreover from assms(1) have "f (\ f) \ carrier L" + by (auto) + ultimately show ?thesis + using fb by blast + qed +qed + + +subsubsection \Greatest fixed points\ + +lemma GFP_closed [intro, simp]: + "\ f \ carrier L" + by (auto intro:sup_closed simp add:GFP_def) + +lemma GFP_upperbound: + assumes "x \ carrier L" "x \ f x" + shows "x \ \ f" + by (auto intro:sup_upper assms simp add:GFP_def) + +lemma GFP_least: + assumes "x \ carrier L" + "(\u. \ u \ carrier L; u \ f u \ \ u \ x)" + shows "\ f \ x" + by (auto simp add:GFP_def intro:sup_least assms) + +lemma GFP_lemma2: + assumes "Mono f" "f \ carrier L \ carrier L" + shows "\ f \ f (\ f)" + using assms + apply (auto simp add:Pi_def) + apply (rule GFP_least) + apply (metis GFP_closed) + apply (metis GFP_closed GFP_upperbound le_trans use_iso2) +done + +lemma GFP_lemma3: + assumes "Mono f" "f \ carrier L \ carrier L" + shows "f (\ f) \ \ f" + by (metis GFP_closed GFP_lemma2 GFP_upperbound assms funcset_mem use_iso2) + +lemma GFP_weak_unfold: + "\ Mono f; f \ carrier L \ carrier L \ \ \ f .= f (\ f)" + by (auto intro: GFP_lemma2 GFP_lemma3 funcset_mem) + +lemma (in weak_complete_lattice) GFP_fixed_point [intro]: + assumes "Mono f" "f \ carrier L \ carrier L" + shows "\ f \ fps L f" + using assms +proof - + have "f (\ f) \ carrier L" + using assms(2) by blast + with assms show ?thesis + by (simp add: GFP_weak_unfold fps_def local.sym) +qed + +lemma GFP_greatest_fixed_point: + assumes "Mono f" "f \ carrier L \ carrier L" "x \ fps L f" + shows "x \ \ f" + using assms + by (rule_tac GFP_upperbound, auto simp add: fps_def, meson PiE local.sym weak_refl) + +lemma GFP_idem: + assumes "f \ carrier L \ carrier L" "Mono f" "Idem f" + shows "\ f .= (f \)" +proof (rule weak_le_antisym) + from assms(1) show fb: "f \ \ carrier L" + by (rule funcset_mem, simp) + from assms show mf: "\ f \ carrier L" + by blast + show "f \ \ \ f" + proof - + have "f (f \) .= f \" + by (auto simp add: fps_def fb assms(3) idempotent) + moreover have "f (f \) \ carrier L" + by (rule funcset_mem[of f "carrier L"], simp_all add: assms fb) + ultimately show ?thesis + by (rule_tac GFP_upperbound, simp_all add: fb local.sym) + qed + show "\ f \ f \" + proof - + have "\ f \ f (\ f)" + by (simp add: GFP_lemma2 assms(1) assms(2)) + moreover have "... \ f \" + by (auto intro: use_iso1[of _ f] simp add: assms) + moreover from assms(1) have "f (\ f) \ carrier L" + by (auto) + ultimately show ?thesis + using fb local.le_trans by blast + qed +qed + +end + + +subsection \Complete lattices where @{text eq} is the Equality\ + +locale complete_lattice = partial_order + + assumes sup_exists: + "[| A \ carrier L |] ==> EX s. least L s (Upper L A)" + and inf_exists: + "[| A \ carrier L |] ==> EX i. greatest L i (Lower L A)" + +sublocale complete_lattice \ lattice +proof + fix x y + assume a: "x \ carrier L" "y \ carrier L" + thus "\s. is_lub L s {x, y}" + by (rule_tac sup_exists[of "{x, y}"], auto) + from a show "\s. is_glb L s {x, y}" + by (rule_tac inf_exists[of "{x, y}"], auto) +qed + +sublocale complete_lattice \ weak?: weak_complete_lattice + by standard (auto intro: sup_exists inf_exists) + +lemma complete_lattice_lattice [simp]: + assumes "complete_lattice X" + shows "lattice X" +proof - + interpret c: complete_lattice X + by (simp add: assms) + show ?thesis + by (unfold_locales) +qed + +text \Introduction rule: the usual definition of complete lattice\ + +lemma (in partial_order) complete_latticeI: + assumes sup_exists: + "!!A. [| A \ carrier L |] ==> EX s. least L s (Upper L A)" + and inf_exists: + "!!A. [| A \ carrier L |] ==> EX i. greatest L i (Lower L A)" + shows "complete_lattice L" + by standard (auto intro: sup_exists inf_exists) + +theorem (in partial_order) complete_lattice_criterion1: + assumes top_exists: "EX g. greatest L g (carrier L)" + and inf_exists: + "!!A. [| A \ carrier L; A ~= {} |] ==> EX i. greatest L i (Lower L A)" + shows "complete_lattice L" +proof (rule complete_latticeI) + from top_exists obtain top where top: "greatest L top (carrier L)" .. + fix A + assume L: "A \ carrier L" + let ?B = "Upper L A" + from L top have "top \ ?B" by (fast intro!: Upper_memI intro: greatest_le) + then have B_non_empty: "?B ~= {}" by fast + have B_L: "?B \ carrier L" by simp + from inf_exists [OF B_L B_non_empty] + obtain b where b_inf_B: "greatest L b (Lower L ?B)" .. + have "least L b (Upper L A)" +apply (rule least_UpperI) + apply (rule greatest_le [where A = "Lower L ?B"]) + apply (rule b_inf_B) + apply (rule Lower_memI) + apply (erule Upper_memD [THEN conjunct1]) + apply assumption + apply (rule L) + apply (fast intro: L [THEN subsetD]) + apply (erule greatest_Lower_below [OF b_inf_B]) + apply simp + apply (rule L) +apply (rule greatest_closed [OF b_inf_B]) +done + then show "EX s. least L s (Upper L A)" .. +next + fix A + assume L: "A \ carrier L" + show "EX i. greatest L i (Lower L A)" + proof (cases "A = {}") + case True then show ?thesis + by (simp add: top_exists) + next + case False with L show ?thesis + by (rule inf_exists) + qed +qed + +(* TODO: prove dual version *) + +subsection \Fixed points\ + +context complete_lattice +begin + +lemma LFP_unfold: + "\ Mono f; f \ carrier L \ carrier L \ \ \ f = f (\ f)" + using eq_is_equal weak.LFP_weak_unfold by auto + +lemma LFP_const: + "t \ carrier L \ \ (\ x. t) = t" + by (simp add: local.le_antisym weak.LFP_greatest weak.LFP_lowerbound) + +lemma LFP_id: + "\ id = \" + by (simp add: local.le_antisym weak.LFP_lowerbound) + +lemma GFP_unfold: + "\ Mono f; f \ carrier L \ carrier L \ \ \ f = f (\ f)" + using eq_is_equal weak.GFP_weak_unfold by auto + +lemma GFP_const: + "t \ carrier L \ \ (\ x. t) = t" + by (simp add: local.le_antisym weak.GFP_least weak.GFP_upperbound) + +lemma GFP_id: + "\ id = \" + using weak.GFP_upperbound by auto + +end + + +subsection \Interval complete lattices\ + +context weak_complete_lattice +begin + + lemma at_least_at_most_Sup: + "\ a \ carrier L; b \ carrier L; a \ b \ \ \ \a..b\ .= b" + apply (rule weak_le_antisym) + apply (rule sup_least) + apply (auto simp add: at_least_at_most_closed) + apply (rule sup_upper) + apply (auto simp add: at_least_at_most_closed) + done + + lemma at_least_at_most_Inf: + "\ a \ carrier L; b \ carrier L; a \ b \ \ \ \a..b\ .= a" + apply (rule weak_le_antisym) + apply (rule inf_lower) + apply (auto simp add: at_least_at_most_closed) + apply (rule inf_greatest) + apply (auto simp add: at_least_at_most_closed) + done + +end + +lemma weak_complete_lattice_interval: + assumes "weak_complete_lattice L" "a \ carrier L" "b \ carrier L" "a \\<^bsub>L\<^esub> b" + shows "weak_complete_lattice (L \ carrier := \a..b\\<^bsub>L\<^esub> \)" +proof - + interpret L: weak_complete_lattice L + by (simp add: assms) + interpret weak_partial_order "L \ carrier := \a..b\\<^bsub>L\<^esub> \" + proof - + have "\a..b\\<^bsub>L\<^esub> \ carrier L" + by (auto, simp add: at_least_at_most_def) + thus "weak_partial_order (L\carrier := \a..b\\<^bsub>L\<^esub>\)" + by (simp add: L.weak_partial_order_axioms weak_partial_order_subset) + qed + + show ?thesis + proof + fix A + assume a: "A \ carrier (L\carrier := \a..b\\<^bsub>L\<^esub>\)" + show "\s. is_lub (L\carrier := \a..b\\<^bsub>L\<^esub>\) s A" + proof (cases "A = {}") + case True + thus ?thesis + by (rule_tac x="a" in exI, auto simp add: least_def assms) + next + case False + show ?thesis + proof (rule_tac x="\\<^bsub>L\<^esub> A" in exI, rule least_UpperI, simp_all) + show b:"\ x. x \ A \ x \\<^bsub>L\<^esub> \\<^bsub>L\<^esub>A" + using a by (auto intro: L.sup_upper, meson L.at_least_at_most_closed L.sup_upper subset_trans) + show "\y. y \ Upper (L\carrier := \a..b\\<^bsub>L\<^esub>\) A \ \\<^bsub>L\<^esub>A \\<^bsub>L\<^esub> y" + using a L.at_least_at_most_closed by (rule_tac L.sup_least, auto intro: funcset_mem simp add: Upper_def) + from a show "A \ \a..b\\<^bsub>L\<^esub>" + by (auto) + from a show "\\<^bsub>L\<^esub>A \ \a..b\\<^bsub>L\<^esub>" + apply (rule_tac L.at_least_at_most_member) + apply (auto) + apply (meson L.at_least_at_most_closed L.sup_closed subset_trans) + apply (meson False L.at_least_at_most_closed L.at_least_at_most_lower L.le_trans L.sup_closed b all_not_in_conv assms(2) contra_subsetD subset_trans) + apply (rule L.sup_least) + apply (auto simp add: assms) + using L.at_least_at_most_closed apply blast + done + qed + qed + show "\s. is_glb (L\carrier := \a..b\\<^bsub>L\<^esub>\) s A" + proof (cases "A = {}") + case True + thus ?thesis + by (rule_tac x="b" in exI, auto simp add: greatest_def assms) + next + case False + show ?thesis + proof (rule_tac x="\\<^bsub>L\<^esub> A" in exI, rule greatest_LowerI, simp_all) + show b:"\x. x \ A \ \\<^bsub>L\<^esub>A \\<^bsub>L\<^esub> x" + using a L.at_least_at_most_closed by (force intro!: L.inf_lower) + show "\y. y \ Lower (L\carrier := \a..b\\<^bsub>L\<^esub>\) A \ y \\<^bsub>L\<^esub> \\<^bsub>L\<^esub>A" + using a L.at_least_at_most_closed by (rule_tac L.inf_greatest, auto intro: funcset_carrier' simp add: Lower_def) + from a show "A \ \a..b\\<^bsub>L\<^esub>" + by (auto) + from a show "\\<^bsub>L\<^esub>A \ \a..b\\<^bsub>L\<^esub>" + apply (rule_tac L.at_least_at_most_member) + apply (auto) + apply (meson L.at_least_at_most_closed L.inf_closed subset_trans) + apply (meson L.at_least_at_most_closed L.at_least_at_most_lower L.inf_greatest assms(2) set_rev_mp subset_trans) + apply (meson False L.at_least_at_most_closed L.at_least_at_most_upper L.inf_closed L.le_trans b all_not_in_conv assms(3) contra_subsetD subset_trans) + done + qed + qed + qed +qed + + +subsection \Knaster-Tarski theorem and variants\ + +text \The set of fixed points of a complete lattice is itself a complete lattice\ + +theorem Knaster_Tarski: + assumes "weak_complete_lattice L" "f \ carrier L \ carrier L" "isotone L L f" + shows "weak_complete_lattice (fpl L f)" (is "weak_complete_lattice ?L'") +proof - + interpret L: weak_complete_lattice L + by (simp add: assms) + interpret weak_partial_order ?L' + proof - + have "{x \ carrier L. f x .=\<^bsub>L\<^esub> x} \ carrier L" + by (auto) + thus "weak_partial_order ?L'" + by (simp add: L.weak_partial_order_axioms weak_partial_order_subset) + qed + show ?thesis + proof (unfold_locales, simp_all) + fix A + assume A: "A \ fps L f" + show "\s. is_lub (fpl L f) s A" + proof + from A have AL: "A \ carrier L" + by (meson fps_carrier subset_eq) + + let ?w = "\\<^bsub>L\<^esub> A" + have w: "f (\\<^bsub>L\<^esub>A) \ carrier L" + by (rule funcset_mem[of f "carrier L"], simp_all add: AL assms(2)) + + have pf_w: "(\\<^bsub>L\<^esub> A) \\<^bsub>L\<^esub> f (\\<^bsub>L\<^esub> A)" + by (simp add: A L.weak_sup_pre_fixed_point assms(2) assms(3)) + + have f_top_chain: "f ` \?w..\\<^bsub>L\<^esub>\\<^bsub>L\<^esub> \ \?w..\\<^bsub>L\<^esub>\\<^bsub>L\<^esub>" + proof (auto simp add: at_least_at_most_def) + fix x + assume b: "x \ carrier L" "\\<^bsub>L\<^esub>A \\<^bsub>L\<^esub> x" + from b show fx: "f x \ carrier L" + using assms(2) by blast + show "\\<^bsub>L\<^esub>A \\<^bsub>L\<^esub> f x" + proof - + have "?w \\<^bsub>L\<^esub> f ?w" + proof (rule_tac L.sup_least, simp_all add: AL w) + fix y + assume c: "y \ A" + hence y: "y \ fps L f" + using A subsetCE by blast + with assms have "y .=\<^bsub>L\<^esub> f y" + proof - + from y have "y \ carrier L" + by (simp add: fps_def) + moreover hence "f y \ carrier L" + by (rule_tac funcset_mem[of f "carrier L"], simp_all add: assms) + ultimately show ?thesis using y + by (rule_tac L.sym, simp_all add: L.use_fps) + qed + moreover have "y \\<^bsub>L\<^esub> \\<^bsub>L\<^esub>A" + by (simp add: AL L.sup_upper c(1)) + ultimately show "y \\<^bsub>L\<^esub> f (\\<^bsub>L\<^esub>A)" + by (meson fps_def AL funcset_mem L.refl L.weak_complete_lattice_axioms assms(2) assms(3) c(1) isotone_def rev_subsetD weak_complete_lattice.sup_closed weak_partial_order.le_cong) + qed + thus ?thesis + by (meson AL funcset_mem L.le_trans L.sup_closed assms(2) assms(3) b(1) b(2) use_iso2) + qed + + show "f x \\<^bsub>L\<^esub> \\<^bsub>L\<^esub>" + by (simp add: fx) + qed + + let ?L' = "L\ carrier := \?w..\\<^bsub>L\<^esub>\\<^bsub>L\<^esub> \" + + interpret L': weak_complete_lattice ?L' + by (auto intro: weak_complete_lattice_interval simp add: L.weak_complete_lattice_axioms AL) + + let ?L'' = "L\ carrier := fps L f \" + + show "is_lub ?L'' (\\<^bsub>?L'\<^esub> f) A" + proof (rule least_UpperI, simp_all) + fix x + assume "x \ Upper ?L'' A" + hence "\\<^bsub>?L'\<^esub> f \\<^bsub>?L'\<^esub> x" + apply (rule_tac L'.LFP_lowerbound) + apply (auto simp add: Upper_def) + apply (simp add: A AL L.at_least_at_most_member L.sup_least set_rev_mp) + apply (simp add: Pi_iff assms(2) fps_def, rule_tac L.weak_refl) + apply (auto) + apply (rule funcset_mem[of f "carrier L"], simp_all add: assms(2)) + done + thus " \\<^bsub>?L'\<^esub> f \\<^bsub>L\<^esub> x" + by (simp) + next + fix x + assume xA: "x \ A" + show "x \\<^bsub>L\<^esub> \\<^bsub>?L'\<^esub> f" + proof - + have "\\<^bsub>?L'\<^esub> f \ carrier ?L'" + by blast + thus ?thesis + by (simp, meson AL L.at_least_at_most_closed L.at_least_at_most_lower L.le_trans L.sup_closed L.sup_upper xA subsetCE) + qed + next + show "A \ fps L f" + by (simp add: A) + next + show "\\<^bsub>?L'\<^esub> f \ fps L f" + proof (auto simp add: fps_def) + have "\\<^bsub>?L'\<^esub> f \ carrier ?L'" + by (rule L'.LFP_closed) + thus c:"\\<^bsub>?L'\<^esub> f \ carrier L" + by (auto simp add: at_least_at_most_def) + have "\\<^bsub>?L'\<^esub> f .=\<^bsub>?L'\<^esub> f (\\<^bsub>?L'\<^esub> f)" + proof (rule "L'.LFP_weak_unfold", simp_all) + show "f \ \\\<^bsub>L\<^esub>A..\\<^bsub>L\<^esub>\\<^bsub>L\<^esub> \ \\\<^bsub>L\<^esub>A..\\<^bsub>L\<^esub>\\<^bsub>L\<^esub>" + apply (auto simp add: Pi_def at_least_at_most_def) + using assms(2) apply blast + apply (meson AL funcset_mem L.le_trans L.sup_closed assms(2) assms(3) pf_w use_iso2) + using assms(2) apply blast + done + from assms(3) show "Mono\<^bsub>L\carrier := \\\<^bsub>L\<^esub>A..\\<^bsub>L\<^esub>\\<^bsub>L\<^esub>\\<^esub> f" + apply (auto simp add: isotone_def) + using L'.weak_partial_order_axioms apply blast + apply (meson L.at_least_at_most_closed subsetCE) + done + qed + thus "f (\\<^bsub>?L'\<^esub> f) .=\<^bsub>L\<^esub> \\<^bsub>?L'\<^esub> f" + by (simp add: L.equivalence_axioms funcset_carrier' c assms(2) equivalence.sym) + qed + qed + qed + show "\i. is_glb (L\carrier := fps L f\) i A" + proof + from A have AL: "A \ carrier L" + by (meson fps_carrier subset_eq) + + let ?w = "\\<^bsub>L\<^esub> A" + have w: "f (\\<^bsub>L\<^esub>A) \ carrier L" + by (simp add: AL funcset_carrier' assms(2)) + + have pf_w: "f (\\<^bsub>L\<^esub> A) \\<^bsub>L\<^esub> (\\<^bsub>L\<^esub> A)" + by (simp add: A L.weak_sup_post_fixed_point assms(2) assms(3)) + + have f_bot_chain: "f ` \\\<^bsub>L\<^esub>..?w\\<^bsub>L\<^esub> \ \\\<^bsub>L\<^esub>..?w\\<^bsub>L\<^esub>" + proof (auto simp add: at_least_at_most_def) + fix x + assume b: "x \ carrier L" "x \\<^bsub>L\<^esub> \\<^bsub>L\<^esub>A" + from b show fx: "f x \ carrier L" + using assms(2) by blast + show "f x \\<^bsub>L\<^esub> \\<^bsub>L\<^esub>A" + proof - + have "f ?w \\<^bsub>L\<^esub> ?w" + proof (rule_tac L.inf_greatest, simp_all add: AL w) + fix y + assume c: "y \ A" + with assms have "y .=\<^bsub>L\<^esub> f y" + by (metis (no_types, lifting) A funcset_carrier'[OF assms(2)] L.sym fps_def mem_Collect_eq subset_eq) + moreover have "\\<^bsub>L\<^esub>A \\<^bsub>L\<^esub> y" + by (simp add: AL L.inf_lower c) + ultimately show "f (\\<^bsub>L\<^esub>A) \\<^bsub>L\<^esub> y" + by (meson AL L.inf_closed L.le_trans c pf_w set_rev_mp w) + qed + thus ?thesis + by (meson AL L.inf_closed L.le_trans assms(3) b(1) b(2) fx use_iso2 w) + qed + + show "\\<^bsub>L\<^esub> \\<^bsub>L\<^esub> f x" + by (simp add: fx) + qed + + let ?L' = "L\ carrier := \\\<^bsub>L\<^esub>..?w\\<^bsub>L\<^esub> \" + + interpret L': weak_complete_lattice ?L' + by (auto intro!: weak_complete_lattice_interval simp add: L.weak_complete_lattice_axioms AL) + + let ?L'' = "L\ carrier := fps L f \" + + show "is_glb ?L'' (\\<^bsub>?L'\<^esub> f) A" + proof (rule greatest_LowerI, simp_all) + fix x + assume "x \ Lower ?L'' A" + hence "x \\<^bsub>?L'\<^esub> \\<^bsub>?L'\<^esub> f" + apply (rule_tac L'.GFP_upperbound) + apply (auto simp add: Lower_def) + apply (meson A AL L.at_least_at_most_member L.bottom_lower L.weak_complete_lattice_axioms fps_carrier subsetCE weak_complete_lattice.inf_greatest) + apply (simp add: funcset_carrier' L.sym assms(2) fps_def) + done + thus "x \\<^bsub>L\<^esub> \\<^bsub>?L'\<^esub> f" + by (simp) + next + fix x + assume xA: "x \ A" + show "\\<^bsub>?L'\<^esub> f \\<^bsub>L\<^esub> x" + proof - + have "\\<^bsub>?L'\<^esub> f \ carrier ?L'" + by blast + thus ?thesis + by (simp, meson AL L.at_least_at_most_closed L.at_least_at_most_upper L.inf_closed L.inf_lower L.le_trans subsetCE xA) + qed + next + show "A \ fps L f" + by (simp add: A) + next + show "\\<^bsub>?L'\<^esub> f \ fps L f" + proof (auto simp add: fps_def) + have "\\<^bsub>?L'\<^esub> f \ carrier ?L'" + by (rule L'.GFP_closed) + thus c:"\\<^bsub>?L'\<^esub> f \ carrier L" + by (auto simp add: at_least_at_most_def) + have "\\<^bsub>?L'\<^esub> f .=\<^bsub>?L'\<^esub> f (\\<^bsub>?L'\<^esub> f)" + proof (rule "L'.GFP_weak_unfold", simp_all) + show "f \ \\\<^bsub>L\<^esub>..?w\\<^bsub>L\<^esub> \ \\\<^bsub>L\<^esub>..?w\\<^bsub>L\<^esub>" + apply (auto simp add: Pi_def at_least_at_most_def) + using assms(2) apply blast + apply (simp add: funcset_carrier' assms(2)) + apply (meson AL funcset_carrier L.inf_closed L.le_trans assms(2) assms(3) pf_w use_iso2) + done + from assms(3) show "Mono\<^bsub>L\carrier := \\\<^bsub>L\<^esub>..?w\\<^bsub>L\<^esub>\\<^esub> f" + apply (auto simp add: isotone_def) + using L'.weak_partial_order_axioms apply blast + using L.at_least_at_most_closed apply (blast intro: funcset_carrier') + done + qed + thus "f (\\<^bsub>?L'\<^esub> f) .=\<^bsub>L\<^esub> \\<^bsub>?L'\<^esub> f" + by (simp add: L.equivalence_axioms funcset_carrier' c assms(2) equivalence.sym) + qed + qed + qed + qed +qed + +theorem Knaster_Tarski_top: + assumes "weak_complete_lattice L" "isotone L L f" "f \ carrier L \ carrier L" + shows "\\<^bsub>fpl L f\<^esub> .=\<^bsub>L\<^esub> \\<^bsub>L\<^esub> f" +proof - + interpret L: weak_complete_lattice L + by (simp add: assms) + interpret L': weak_complete_lattice "fpl L f" + by (rule Knaster_Tarski, simp_all add: assms) + show ?thesis + proof (rule L.weak_le_antisym, simp_all) + show "\\<^bsub>fpl L f\<^esub> \\<^bsub>L\<^esub> \\<^bsub>L\<^esub> f" + by (rule L.GFP_greatest_fixed_point, simp_all add: assms L'.top_closed[simplified]) + show "\\<^bsub>L\<^esub> f \\<^bsub>L\<^esub> \\<^bsub>fpl L f\<^esub>" + proof - + have "\\<^bsub>L\<^esub> f \ fps L f" + by (rule L.GFP_fixed_point, simp_all add: assms) + hence "\\<^bsub>L\<^esub> f \ carrier (fpl L f)" + by simp + hence "\\<^bsub>L\<^esub> f \\<^bsub>fpl L f\<^esub> \\<^bsub>fpl L f\<^esub>" + by (rule L'.top_higher) + thus ?thesis + by simp + qed + show "\\<^bsub>fpl L f\<^esub> \ carrier L" + proof - + have "carrier (fpl L f) \ carrier L" + by (auto simp add: fps_def) + with L'.top_closed show ?thesis + by blast + qed + qed +qed + +theorem Knaster_Tarski_bottom: + assumes "weak_complete_lattice L" "isotone L L f" "f \ carrier L \ carrier L" + shows "\\<^bsub>fpl L f\<^esub> .=\<^bsub>L\<^esub> \\<^bsub>L\<^esub> f" +proof - + interpret L: weak_complete_lattice L + by (simp add: assms) + interpret L': weak_complete_lattice "fpl L f" + by (rule Knaster_Tarski, simp_all add: assms) + show ?thesis + proof (rule L.weak_le_antisym, simp_all) + show "\\<^bsub>L\<^esub> f \\<^bsub>L\<^esub> \\<^bsub>fpl L f\<^esub>" + by (rule L.LFP_least_fixed_point, simp_all add: assms L'.bottom_closed[simplified]) + show "\\<^bsub>fpl L f\<^esub> \\<^bsub>L\<^esub> \\<^bsub>L\<^esub> f" + proof - + have "\\<^bsub>L\<^esub> f \ fps L f" + by (rule L.LFP_fixed_point, simp_all add: assms) + hence "\\<^bsub>L\<^esub> f \ carrier (fpl L f)" + by simp + hence "\\<^bsub>fpl L f\<^esub> \\<^bsub>fpl L f\<^esub> \\<^bsub>L\<^esub> f" + by (rule L'.bottom_lower) + thus ?thesis + by simp + qed + show "\\<^bsub>fpl L f\<^esub> \ carrier L" + proof - + have "carrier (fpl L f) \ carrier L" + by (auto simp add: fps_def) + with L'.bottom_closed show ?thesis + by blast + qed + qed +qed + +text \If a function is both idempotent and isotone then the image of the function forms a complete lattice\ + +theorem Knaster_Tarski_idem: + assumes "complete_lattice L" "f \ carrier L \ carrier L" "isotone L L f" "idempotent L f" + shows "complete_lattice (L\carrier := f ` carrier L\)" +proof - + interpret L: complete_lattice L + by (simp add: assms) + have "fps L f = f ` carrier L" + using L.weak.fps_idem[OF assms(2) assms(4)] + by (simp add: L.set_eq_is_eq) + then interpret L': weak_complete_lattice "(L\carrier := f ` carrier L\)" + by (metis Knaster_Tarski L.weak.weak_complete_lattice_axioms assms(2) assms(3)) + show ?thesis + using L'.sup_exists L'.inf_exists + by (unfold_locales, auto simp add: L.eq_is_equal) +qed + +theorem Knaster_Tarski_idem_extremes: + assumes "weak_complete_lattice L" "isotone L L f" "idempotent L f" "f \ carrier L \ carrier L" + shows "\\<^bsub>fpl L f\<^esub> .=\<^bsub>L\<^esub> f (\\<^bsub>L\<^esub>)" "\\<^bsub>fpl L f\<^esub> .=\<^bsub>L\<^esub> f (\\<^bsub>L\<^esub>)" +proof - + interpret L: weak_complete_lattice "L" + by (simp_all add: assms) + interpret L': weak_complete_lattice "fpl L f" + by (rule Knaster_Tarski, simp_all add: assms) + have FA: "fps L f \ carrier L" + by (auto simp add: fps_def) + show "\\<^bsub>fpl L f\<^esub> .=\<^bsub>L\<^esub> f (\\<^bsub>L\<^esub>)" + proof - + from FA have "\\<^bsub>fpl L f\<^esub> \ carrier L" + proof - + have "\\<^bsub>fpl L f\<^esub> \ fps L f" + using L'.top_closed by auto + thus ?thesis + using FA by blast + qed + moreover with assms have "f \\<^bsub>L\<^esub> \ carrier L" + by (auto) + + ultimately show ?thesis + using L.trans[OF Knaster_Tarski_top[of L f] L.GFP_idem[of f]] + by (simp_all add: assms) + qed + show "\\<^bsub>fpl L f\<^esub> .=\<^bsub>L\<^esub> f (\\<^bsub>L\<^esub>)" + proof - + from FA have "\\<^bsub>fpl L f\<^esub> \ carrier L" + proof - + have "\\<^bsub>fpl L f\<^esub> \ fps L f" + using L'.bottom_closed by auto + thus ?thesis + using FA by blast + qed + moreover with assms have "f \\<^bsub>L\<^esub> \ carrier L" + by (auto) + + ultimately show ?thesis + using L.trans[OF Knaster_Tarski_bottom[of L f] L.LFP_idem[of f]] + by (simp_all add: assms) + qed +qed + + +subsection \Examples\ + +subsubsection \The Powerset of a Set is a Complete Lattice\ + +theorem powerset_is_complete_lattice: + "complete_lattice \carrier = Pow A, eq = op =, le = op \\" + (is "complete_lattice ?L") +proof (rule partial_order.complete_latticeI) + show "partial_order ?L" + by standard auto +next + fix B + assume "B \ carrier ?L" + then have "least ?L (\ B) (Upper ?L B)" + by (fastforce intro!: least_UpperI simp: Upper_def) + then show "EX s. least ?L s (Upper ?L B)" .. +next + fix B + assume "B \ carrier ?L" + then have "greatest ?L (\ B \ A) (Lower ?L B)" + txt \@{term "\ B"} is not the infimum of @{term B}: + @{term "\ {} = UNIV"} which is in general bigger than @{term "A"}! \ + by (fastforce intro!: greatest_LowerI simp: Lower_def) + then show "EX i. greatest ?L i (Lower ?L B)" .. +qed + +text \Another example, that of the lattice of subgroups of a group, + can be found in Group theory (Section~\ref{sec:subgroup-lattice}).\ + + +subsection \Limit preserving functions\ + +definition weak_sup_pres :: "('a, 'c) gorder_scheme \ ('b, 'd) gorder_scheme \ ('a \ 'b) \ bool" where +"weak_sup_pres X Y f \ complete_lattice X \ complete_lattice Y \ (\ A \ carrier X. A \ {} \ f (\\<^bsub>X\<^esub> A) = (\\<^bsub>Y\<^esub> (f ` A)))" + +definition sup_pres :: "('a, 'c) gorder_scheme \ ('b, 'd) gorder_scheme \ ('a \ 'b) \ bool" where +"sup_pres X Y f \ complete_lattice X \ complete_lattice Y \ (\ A \ carrier X. f (\\<^bsub>X\<^esub> A) = (\\<^bsub>Y\<^esub> (f ` A)))" + +definition weak_inf_pres :: "('a, 'c) gorder_scheme \ ('b, 'd) gorder_scheme \ ('a \ 'b) \ bool" where +"weak_inf_pres X Y f \ complete_lattice X \ complete_lattice Y \ (\ A \ carrier X. A \ {} \ f (\\<^bsub>X\<^esub> A) = (\\<^bsub>Y\<^esub> (f ` A)))" + +definition inf_pres :: "('a, 'c) gorder_scheme \ ('b, 'd) gorder_scheme \ ('a \ 'b) \ bool" where +"inf_pres X Y f \ complete_lattice X \ complete_lattice Y \ (\ A \ carrier X. f (\\<^bsub>X\<^esub> A) = (\\<^bsub>Y\<^esub> (f ` A)))" + +lemma weak_sup_pres: + "sup_pres X Y f \ weak_sup_pres X Y f" + by (simp add: sup_pres_def weak_sup_pres_def) + +lemma weak_inf_pres: + "inf_pres X Y f \ weak_inf_pres X Y f" + by (simp add: inf_pres_def weak_inf_pres_def) + +lemma sup_pres_is_join_pres: + assumes "weak_sup_pres X Y f" + shows "join_pres X Y f" + using assms + apply (simp add: join_pres_def weak_sup_pres_def, safe) + apply (rename_tac x y) + apply (drule_tac x="{x, y}" in spec) + apply (auto simp add: join_def) +done + +lemma inf_pres_is_meet_pres: + assumes "weak_inf_pres X Y f" + shows "meet_pres X Y f" + using assms + apply (simp add: meet_pres_def weak_inf_pres_def, safe) + apply (rename_tac x y) + apply (drule_tac x="{x, y}" in spec) + apply (auto simp add: meet_def) +done + +end diff -r b47ba1778e44 -r 30d0b2f1df76 src/HOL/Algebra/Congruence.thy --- a/src/HOL/Algebra/Congruence.thy Fri Mar 03 23:21:24 2017 +0100 +++ b/src/HOL/Algebra/Congruence.thy Thu Mar 02 21:16:02 2017 +0100 @@ -4,7 +4,9 @@ *) theory Congruence -imports Main +imports + Main + "~~/src/HOL/Library/FuncSet" begin section \Objects\ @@ -14,6 +16,14 @@ record 'a partial_object = carrier :: "'a set" +lemma funcset_carrier: + "\ f \ carrier X \ carrier Y; x \ carrier X \ \ f x \ carrier Y" + by (fact funcset_mem) + +lemma funcset_carrier': + "\ f \ carrier A \ carrier A; x \ carrier A \ \ f x \ carrier A" + by (fact funcset_mem) + subsection \Structure with Carrier and Equivalence Relation \eq\\ @@ -413,4 +423,14 @@ by (blast intro: closure_of_memI elem_exact dest: is_closedD1 is_closedD2 closure_of_memE) *) +lemma equivalence_subset: + assumes "equivalence L" "A \ carrier L" + shows "equivalence (L\ carrier := A \)" +proof - + interpret L: equivalence L + by (simp add: assms) + show ?thesis + by (unfold_locales, simp_all add: L.sym assms rev_subsetD, meson L.trans assms(2) contra_subsetD) +qed + end diff -r b47ba1778e44 -r 30d0b2f1df76 src/HOL/Algebra/Galois_Connection.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Algebra/Galois_Connection.thy Thu Mar 02 21:16:02 2017 +0100 @@ -0,0 +1,422 @@ +(* Title: HOL/Algebra/Galois_Connection.thy + Author: Alasdair Armstrong and Simon Foster + Copyright: Alasdair Armstrong and Simon Foster +*) + +theory Galois_Connection + imports Complete_Lattice +begin + +section \Galois connections\ + +subsection \Definition and basic properties\ + +record ('a, 'b, 'c, 'd) galcon = + orderA :: "('a, 'c) gorder_scheme" ("\\") + orderB :: "('b, 'd) gorder_scheme" ("\\") + lower :: "'a \ 'b" ("\\<^sup>*\") + upper :: "'b \ 'a" ("\\<^sub>*\") + +type_synonym ('a, 'b) galois = "('a, 'b, unit, unit) galcon" + +abbreviation "inv_galcon G \ \ orderA = inv_gorder \\<^bsub>G\<^esub>, orderB = inv_gorder \\<^bsub>G\<^esub>, lower = upper G, upper = lower G \" + +definition comp_galcon :: "('b, 'c) galois \ ('a, 'b) galois \ ('a, 'c) galois" (infixr "\\<^sub>g" 85) + where "G \\<^sub>g F = \ orderA = orderA F, orderB = orderB G, lower = lower G \ lower F, upper = upper F \ upper G \" + +definition id_galcon :: "'a gorder \ ('a, 'a) galois" ("I\<^sub>g") where +"I\<^sub>g(A) = \ orderA = A, orderB = A, lower = id, upper = id \" + + +subsection \Well-typed connections\ + +locale connection = + fixes G (structure) + assumes is_order_A: "partial_order \" + and is_order_B: "partial_order \" + and lower_closure: "\\<^sup>* \ carrier \ \ carrier \" + and upper_closure: "\\<^sub>* \ carrier \ \ carrier \" +begin + + lemma lower_closed: "x \ carrier \ \ \\<^sup>* x \ carrier \" + using lower_closure by auto + + lemma upper_closed: "y \ carrier \ \ \\<^sub>* y \ carrier \" + using upper_closure by auto + +end + + +subsection \Galois connections\ + +locale galois_connection = connection + + assumes galois_property: "\x \ carrier \; y \ carrier \\ \ \\<^sup>* x \\<^bsub>\\<^esub> y \ x \\<^bsub>\\<^esub> \\<^sub>* y" +begin + + lemma is_weak_order_A: "weak_partial_order \" + proof - + interpret po: partial_order \ + by (metis is_order_A) + show ?thesis .. + qed + + lemma is_weak_order_B: "weak_partial_order \" + proof - + interpret po: partial_order \ + by (metis is_order_B) + show ?thesis .. + qed + + lemma right: "\x \ carrier \; y \ carrier \; \\<^sup>* x \\<^bsub>\\<^esub> y\ \ x \\<^bsub>\\<^esub> \\<^sub>* y" + by (metis galois_property) + + lemma left: "\x \ carrier \; y \ carrier \; x \\<^bsub>\\<^esub> \\<^sub>* y\ \ \\<^sup>* x \\<^bsub>\\<^esub> y" + by (metis galois_property) + + lemma deflation: "y \ carrier \ \ \\<^sup>* (\\<^sub>* y) \\<^bsub>\\<^esub> y" + by (metis Pi_iff is_weak_order_A left upper_closure weak_partial_order.le_refl) + + lemma inflation: "x \ carrier \ \ x \\<^bsub>\\<^esub> \\<^sub>* (\\<^sup>* x)" + by (metis (no_types, lifting) PiE galois_connection.right galois_connection_axioms is_weak_order_B lower_closure weak_partial_order.le_refl) + + lemma lower_iso: "isotone \ \ \\<^sup>*" + proof (auto simp add:isotone_def) + show "weak_partial_order \" + by (metis is_weak_order_A) + show "weak_partial_order \" + by (metis is_weak_order_B) + fix x y + assume a: "x \ carrier \" "y \ carrier \" "x \\<^bsub>\\<^esub> y" + have b: "\\<^sup>* y \ carrier \" + using a(2) lower_closure by blast + then have "\\<^sub>* (\\<^sup>* y) \ carrier \" + using upper_closure by blast + then have "x \\<^bsub>\\<^esub> \\<^sub>* (\\<^sup>* y)" + by (meson a inflation is_weak_order_A weak_partial_order.le_trans) + thus "\\<^sup>* x \\<^bsub>\\<^esub> \\<^sup>* y" + by (meson b a(1) Pi_iff galois_property lower_closure upper_closure) + qed + + lemma upper_iso: "isotone \ \ \\<^sub>*" + apply (auto simp add:isotone_def) + apply (metis is_weak_order_B) + apply (metis is_weak_order_A) + apply (metis (no_types, lifting) Pi_mem deflation is_weak_order_B lower_closure right upper_closure weak_partial_order.le_trans) + done + + lemma lower_comp: "x \ carrier \ \ \\<^sup>* (\\<^sub>* (\\<^sup>* x)) = \\<^sup>* x" + by (meson deflation funcset_mem inflation is_order_B lower_closure lower_iso partial_order.le_antisym upper_closure use_iso2) + + lemma lower_comp': "x \ carrier \ \ (\\<^sup>* \ \\<^sub>* \ \\<^sup>*) x = \\<^sup>* x" + by (simp add: lower_comp) + + lemma upper_comp: "y \ carrier \ \ \\<^sub>* (\\<^sup>* (\\<^sub>* y)) = \\<^sub>* y" + proof - + assume a1: "y \ carrier \" + hence f1: "\\<^sub>* y \ carrier \" using upper_closure by blast + have f2: "\\<^sup>* (\\<^sub>* y) \\<^bsub>\\<^esub> y" using a1 deflation by blast + have f3: "\\<^sub>* (\\<^sup>* (\\<^sub>* y)) \ carrier \" + using f1 lower_closure upper_closure by auto + have "\\<^sup>* (\\<^sub>* y) \ carrier \" using f1 lower_closure by blast + thus "\\<^sub>* (\\<^sup>* (\\<^sub>* y)) = \\<^sub>* y" + by (meson a1 f1 f2 f3 inflation is_order_A partial_order.le_antisym upper_iso use_iso2) + qed + + lemma upper_comp': "y \ carrier \ \ (\\<^sub>* \ \\<^sup>* \ \\<^sub>*) y = \\<^sub>* y" + by (simp add: upper_comp) + + lemma adjoint_idem1: "idempotent \ (\\<^sup>* \ \\<^sub>*)" + by (simp add: idempotent_def is_order_B partial_order.eq_is_equal upper_comp) + + lemma adjoint_idem2: "idempotent \ (\\<^sub>* \ \\<^sup>*)" + by (simp add: idempotent_def is_order_A partial_order.eq_is_equal lower_comp) + + lemma fg_iso: "isotone \ \ (\\<^sup>* \ \\<^sub>*)" + by (metis iso_compose lower_closure lower_iso upper_closure upper_iso) + + lemma gf_iso: "isotone \ \ (\\<^sub>* \ \\<^sup>*)" + by (metis iso_compose lower_closure lower_iso upper_closure upper_iso) + + lemma semi_inverse1: "x \ carrier \ \ \\<^sup>* x = \\<^sup>* (\\<^sub>* (\\<^sup>* x))" + by (metis lower_comp) + + lemma semi_inverse2: "x \ carrier \ \ \\<^sub>* x = \\<^sub>* (\\<^sup>* (\\<^sub>* x))" + by (metis upper_comp) + + theorem lower_by_complete_lattice: + assumes "complete_lattice \" "x \ carrier \" + shows "\\<^sup>*(x) = \\<^bsub>\\<^esub> { y \ carrier \. x \\<^bsub>\\<^esub> \\<^sub>*(y) }" + proof - + interpret Y: complete_lattice \ + by (simp add: assms) + + show ?thesis + proof (rule Y.le_antisym) + show x: "\\<^sup>* x \ carrier \" + using assms(2) lower_closure by blast + show "\\<^sup>* x \\<^bsub>\\<^esub> \\<^bsub>\\<^esub>{y \ carrier \. x \\<^bsub>\\<^esub> \\<^sub>* y}" + proof (rule Y.weak.inf_greatest) + show "{y \ carrier \. x \\<^bsub>\\<^esub> \\<^sub>* y} \ carrier \" + by auto + show "\\<^sup>* x \ carrier \" by (fact x) + fix z + assume "z \ {y \ carrier \. x \\<^bsub>\\<^esub> \\<^sub>* y}" + thus "\\<^sup>* x \\<^bsub>\\<^esub> z" + using assms(2) left by auto + qed + show "\\<^bsub>\\<^esub>{y \ carrier \. x \\<^bsub>\\<^esub> \\<^sub>* y} \\<^bsub>\\<^esub> \\<^sup>* x" + proof (rule Y.weak.inf_lower) + show "{y \ carrier \. x \\<^bsub>\\<^esub> \\<^sub>* y} \ carrier \" + by auto + show "\\<^sup>* x \ {y \ carrier \. x \\<^bsub>\\<^esub> \\<^sub>* y}" + proof (auto) + show "\\<^sup>* x \ carrier \" by (fact x) + show "x \\<^bsub>\\<^esub> \\<^sub>* (\\<^sup>* x)" + using assms(2) inflation by blast + qed + qed + show "\\<^bsub>\\<^esub>{y \ carrier \. x \\<^bsub>\\<^esub> \\<^sub>* y} \ carrier \" + by (auto intro: Y.weak.inf_closed) + qed + qed + + theorem upper_by_complete_lattice: + assumes "complete_lattice \" "y \ carrier \" + shows "\\<^sub>*(y) = \\<^bsub>\\<^esub> { x \ carrier \. \\<^sup>*(x) \\<^bsub>\\<^esub> y }" + proof - + interpret X: complete_lattice \ + by (simp add: assms) + show ?thesis + proof (rule X.le_antisym) + show y: "\\<^sub>* y \ carrier \" + using assms(2) upper_closure by blast + show "\\<^sub>* y \\<^bsub>\\<^esub> \\<^bsub>\\<^esub>{x \ carrier \. \\<^sup>* x \\<^bsub>\\<^esub> y}" + proof (rule X.weak.sup_upper) + show "{x \ carrier \. \\<^sup>* x \\<^bsub>\\<^esub> y} \ carrier \" + by auto + show "\\<^sub>* y \ {x \ carrier \. \\<^sup>* x \\<^bsub>\\<^esub> y}" + proof (auto) + show "\\<^sub>* y \ carrier \" by (fact y) + show "\\<^sup>* (\\<^sub>* y) \\<^bsub>\\<^esub> y" + by (simp add: assms(2) deflation) + qed + qed + show "\\<^bsub>\\<^esub>{x \ carrier \. \\<^sup>* x \\<^bsub>\\<^esub> y} \\<^bsub>\\<^esub> \\<^sub>* y" + proof (rule X.weak.sup_least) + show "{x \ carrier \. \\<^sup>* x \\<^bsub>\\<^esub> y} \ carrier \" + by auto + show "\\<^sub>* y \ carrier \" by (fact y) + fix z + assume "z \ {x \ carrier \. \\<^sup>* x \\<^bsub>\\<^esub> y}" + thus "z \\<^bsub>\\<^esub> \\<^sub>* y" + by (simp add: assms(2) right) + qed + show "\\<^bsub>\\<^esub>{x \ carrier \. \\<^sup>* x \\<^bsub>\\<^esub> y} \ carrier \" + by (auto intro: X.weak.sup_closed) + qed + qed + +end + +lemma dual_galois [simp]: " galois_connection \ orderA = inv_gorder B, orderB = inv_gorder A, lower = f, upper = g \ + = galois_connection \ orderA = A, orderB = B, lower = g, upper = f \" + by (auto simp add: galois_connection_def galois_connection_axioms_def connection_def dual_order_iff) + +definition lower_adjoint :: "('a, 'c) gorder_scheme \ ('b, 'd) gorder_scheme \ ('a \ 'b) \ bool" where + "lower_adjoint A B f \ \g. galois_connection \ orderA = A, orderB = B, lower = f, upper = g \" + +definition upper_adjoint :: "('a, 'c) gorder_scheme \ ('b, 'd) gorder_scheme \ ('b \ 'a) \ bool" where + "upper_adjoint A B g \ \f. galois_connection \ orderA = A, orderB = B, lower = f, upper = g \" + +lemma lower_adjoint_dual [simp]: "lower_adjoint (inv_gorder A) (inv_gorder B) f = upper_adjoint B A f" + by (simp add: lower_adjoint_def upper_adjoint_def) + +lemma upper_adjoint_dual [simp]: "upper_adjoint (inv_gorder A) (inv_gorder B) f = lower_adjoint B A f" + by (simp add: lower_adjoint_def upper_adjoint_def) + +lemma lower_type: "lower_adjoint A B f \ f \ carrier A \ carrier B" + by (auto simp add:lower_adjoint_def galois_connection_def galois_connection_axioms_def connection_def) + +lemma upper_type: "upper_adjoint A B g \ g \ carrier B \ carrier A" + by (auto simp add:upper_adjoint_def galois_connection_def galois_connection_axioms_def connection_def) + + +subsection \Composition of Galois connections\ + +lemma id_galois: "partial_order A \ galois_connection (I\<^sub>g(A))" + by (simp add: id_galcon_def galois_connection_def galois_connection_axioms_def connection_def) + +lemma comp_galcon_closed: + assumes "galois_connection G" "galois_connection F" "\\<^bsub>F\<^esub> = \\<^bsub>G\<^esub>" + shows "galois_connection (G \\<^sub>g F)" +proof - + interpret F: galois_connection F + by (simp add: assms) + interpret G: galois_connection G + by (simp add: assms) + + have "partial_order \\<^bsub>G \\<^sub>g F\<^esub>" + by (simp add: F.is_order_A comp_galcon_def) + moreover have "partial_order \\<^bsub>G \\<^sub>g F\<^esub>" + by (simp add: G.is_order_B comp_galcon_def) + moreover have "\\<^sup>*\<^bsub>G\<^esub> \ \\<^sup>*\<^bsub>F\<^esub> \ carrier \\<^bsub>F\<^esub> \ carrier \\<^bsub>G\<^esub>" + using F.lower_closure G.lower_closure assms(3) by auto + moreover have "\\<^sub>*\<^bsub>F\<^esub> \ \\<^sub>*\<^bsub>G\<^esub> \ carrier \\<^bsub>G\<^esub> \ carrier \\<^bsub>F\<^esub>" + using F.upper_closure G.upper_closure assms(3) by auto + moreover + have "\ x y. \x \ carrier \\<^bsub>F\<^esub>; y \ carrier \\<^bsub>G\<^esub> \ \ + (\\<^sup>*\<^bsub>G\<^esub> (\\<^sup>*\<^bsub>F\<^esub> x) \\<^bsub>\\<^bsub>G\<^esub>\<^esub> y) = (x \\<^bsub>\\<^bsub>F\<^esub>\<^esub> \\<^sub>*\<^bsub>F\<^esub> (\\<^sub>*\<^bsub>G\<^esub> y))" + by (metis F.galois_property F.lower_closure G.galois_property G.upper_closure assms(3) Pi_iff) + ultimately show ?thesis + by (simp add: comp_galcon_def galois_connection_def galois_connection_axioms_def connection_def) +qed + +lemma comp_galcon_right_unit [simp]: "F \\<^sub>g I\<^sub>g(\\<^bsub>F\<^esub>) = F" + by (simp add: comp_galcon_def id_galcon_def) + +lemma comp_galcon_left_unit [simp]: "I\<^sub>g(\\<^bsub>F\<^esub>) \\<^sub>g F = F" + by (simp add: comp_galcon_def id_galcon_def) + +lemma galois_connectionI: + assumes + "partial_order A" "partial_order B" + "L \ carrier A \ carrier B" "R \ carrier B \ carrier A" + "isotone A B L" "isotone B A R" + "\ x y. \ x \ carrier A; y \ carrier B \ \ L x \\<^bsub>B\<^esub> y \ x \\<^bsub>A\<^esub> R y" + shows "galois_connection \ orderA = A, orderB = B, lower = L, upper = R \" + using assms by (simp add: galois_connection_def connection_def galois_connection_axioms_def) + +lemma galois_connectionI': + assumes + "partial_order A" "partial_order B" + "L \ carrier A \ carrier B" "R \ carrier B \ carrier A" + "isotone A B L" "isotone B A R" + "\ X. X \ carrier(B) \ L(R(X)) \\<^bsub>B\<^esub> X" + "\ X. X \ carrier(A) \ X \\<^bsub>A\<^esub> R(L(X))" + shows "galois_connection \ orderA = A, orderB = B, lower = L, upper = R \" + using assms + by (auto simp add: galois_connection_def connection_def galois_connection_axioms_def, (meson PiE isotone_def weak_partial_order.le_trans)+) + + +subsection \Retracts\ + +locale retract = galois_connection + + assumes retract_property: "x \ carrier \ \ \\<^sub>* (\\<^sup>* x) \\<^bsub>\\<^esub> x" +begin + lemma retract_inverse: "x \ carrier \ \ \\<^sub>* (\\<^sup>* x) = x" + by (meson funcset_mem inflation is_order_A lower_closure partial_order.le_antisym retract_axioms retract_axioms_def retract_def upper_closure) + + lemma retract_injective: "inj_on \\<^sup>* (carrier \)" + by (metis inj_onI retract_inverse) +end + +theorem comp_retract_closed: + assumes "retract G" "retract F" "\\<^bsub>F\<^esub> = \\<^bsub>G\<^esub>" + shows "retract (G \\<^sub>g F)" +proof - + interpret f: retract F + by (simp add: assms) + interpret g: retract G + by (simp add: assms) + interpret gf: galois_connection "(G \\<^sub>g F)" + by (simp add: assms(1) assms(2) assms(3) comp_galcon_closed retract.axioms(1)) + show ?thesis + proof + fix x + assume "x \ carrier \\<^bsub>G \\<^sub>g F\<^esub>" + thus "le \\<^bsub>G \\<^sub>g F\<^esub> (\\<^sub>*\<^bsub>G \\<^sub>g F\<^esub> (\\<^sup>*\<^bsub>G \\<^sub>g F\<^esub> x)) x" + using assms(3) f.inflation f.lower_closed f.retract_inverse g.retract_inverse by (auto simp add: comp_galcon_def) + qed +qed + + +subsection \Coretracts\ + +locale coretract = galois_connection + + assumes coretract_property: "y \ carrier \ \ y \\<^bsub>\\<^esub> \\<^sup>* (\\<^sub>* y)" +begin + lemma coretract_inverse: "y \ carrier \ \ \\<^sup>* (\\<^sub>* y) = y" + by (meson coretract_axioms coretract_axioms_def coretract_def deflation funcset_mem is_order_B lower_closure partial_order.le_antisym upper_closure) + + lemma retract_injective: "inj_on \\<^sub>* (carrier \)" + by (metis coretract_inverse inj_onI) +end + +theorem comp_coretract_closed: + assumes "coretract G" "coretract F" "\\<^bsub>F\<^esub> = \\<^bsub>G\<^esub>" + shows "coretract (G \\<^sub>g F)" +proof - + interpret f: coretract F + by (simp add: assms) + interpret g: coretract G + by (simp add: assms) + interpret gf: galois_connection "(G \\<^sub>g F)" + by (simp add: assms(1) assms(2) assms(3) comp_galcon_closed coretract.axioms(1)) + show ?thesis + proof + fix y + assume "y \ carrier \\<^bsub>G \\<^sub>g F\<^esub>" + thus "le \\<^bsub>G \\<^sub>g F\<^esub> y (\\<^sup>*\<^bsub>G \\<^sub>g F\<^esub> (\\<^sub>*\<^bsub>G \\<^sub>g F\<^esub> y))" + by (simp add: comp_galcon_def assms(3) f.coretract_inverse g.coretract_property g.upper_closed) + qed +qed + + +subsection \Galois Bijections\ + +locale galois_bijection = connection + + assumes lower_iso: "isotone \ \ \\<^sup>*" + and upper_iso: "isotone \ \ \\<^sub>*" + and lower_inv_eq: "x \ carrier \ \ \\<^sub>* (\\<^sup>* x) = x" + and upper_inv_eq: "y \ carrier \ \ \\<^sup>* (\\<^sub>* y) = y" +begin + + lemma lower_bij: "bij_betw \\<^sup>* (carrier \) (carrier \)" + by (rule bij_betwI[where g="\\<^sub>*"], auto intro: upper_inv_eq lower_inv_eq upper_closed lower_closed) + + lemma upper_bij: "bij_betw \\<^sub>* (carrier \) (carrier \)" + by (rule bij_betwI[where g="\\<^sup>*"], auto intro: upper_inv_eq lower_inv_eq upper_closed lower_closed) + +sublocale gal_bij_conn: galois_connection + apply (unfold_locales, auto) + using lower_closed lower_inv_eq upper_iso use_iso2 apply fastforce + using lower_iso upper_closed upper_inv_eq use_iso2 apply fastforce +done + +sublocale gal_bij_ret: retract + by (unfold_locales, simp add: gal_bij_conn.is_weak_order_A lower_inv_eq weak_partial_order.le_refl) + +sublocale gal_bij_coret: coretract + by (unfold_locales, simp add: gal_bij_conn.is_weak_order_B upper_inv_eq weak_partial_order.le_refl) + +end + +theorem comp_galois_bijection_closed: + assumes "galois_bijection G" "galois_bijection F" "\\<^bsub>F\<^esub> = \\<^bsub>G\<^esub>" + shows "galois_bijection (G \\<^sub>g F)" +proof - + interpret f: galois_bijection F + by (simp add: assms) + interpret g: galois_bijection G + by (simp add: assms) + interpret gf: galois_connection "(G \\<^sub>g F)" + by (simp add: assms(3) comp_galcon_closed f.gal_bij_conn.galois_connection_axioms g.gal_bij_conn.galois_connection_axioms galois_connection.axioms(1)) + show ?thesis + proof + show "isotone \\<^bsub>G \\<^sub>g F\<^esub> \\<^bsub>G \\<^sub>g F\<^esub> \\<^sup>*\<^bsub>G \\<^sub>g F\<^esub>" + by (simp add: comp_galcon_def, metis comp_galcon_def galcon.select_convs(1) galcon.select_convs(2) galcon.select_convs(3) gf.lower_iso) + show "isotone \\<^bsub>G \\<^sub>g F\<^esub> \\<^bsub>G \\<^sub>g F\<^esub> \\<^sub>*\<^bsub>G \\<^sub>g F\<^esub>" + by (simp add: gf.upper_iso) + fix x + assume "x \ carrier \\<^bsub>G \\<^sub>g F\<^esub>" + thus "\\<^sub>*\<^bsub>G \\<^sub>g F\<^esub> (\\<^sup>*\<^bsub>G \\<^sub>g F\<^esub> x) = x" + using assms(3) f.lower_closed f.lower_inv_eq g.lower_inv_eq by (auto simp add: comp_galcon_def) + next + fix y + assume "y \ carrier \\<^bsub>G \\<^sub>g F\<^esub>" + thus "\\<^sup>*\<^bsub>G \\<^sub>g F\<^esub> (\\<^sub>*\<^bsub>G \\<^sub>g F\<^esub> y) = y" + by (simp add: comp_galcon_def assms(3) f.upper_inv_eq g.upper_closed g.upper_inv_eq) + qed +qed + +end diff -r b47ba1778e44 -r 30d0b2f1df76 src/HOL/Algebra/Group.thy --- a/src/HOL/Algebra/Group.thy Fri Mar 03 23:21:24 2017 +0100 +++ b/src/HOL/Algebra/Group.thy Thu Mar 02 21:16:02 2017 +0100 @@ -5,7 +5,7 @@ *) theory Group -imports Lattice "~~/src/HOL/Library/FuncSet" +imports Complete_Lattice "~~/src/HOL/Library/FuncSet" begin section \Monoids and Groups\ diff -r b47ba1778e44 -r 30d0b2f1df76 src/HOL/Algebra/Lattice.thy --- a/src/HOL/Algebra/Lattice.thy Fri Mar 03 23:21:24 2017 +0100 +++ b/src/HOL/Algebra/Lattice.thy Thu Mar 02 21:16:02 2017 +0100 @@ -3,406 +3,16 @@ Copyright: Clemens Ballarin Most congruence rules by Stephan Hohe. +With additional contributions from Alasdair Armstrong and Simon Foster. *) theory Lattice -imports Congruence -begin - -section \Orders and Lattices\ - -subsection \Partial Orders\ - -record 'a gorder = "'a eq_object" + - le :: "['a, 'a] => bool" (infixl "\\" 50) - -locale weak_partial_order = equivalence L for L (structure) + - assumes le_refl [intro, simp]: - "x \ carrier L ==> x \ x" - and weak_le_antisym [intro]: - "[| x \ y; y \ x; x \ carrier L; y \ carrier L |] ==> x .= y" - and le_trans [trans]: - "[| x \ y; y \ z; x \ carrier L; y \ carrier L; z \ carrier L |] ==> x \ z" - and le_cong: - "\ x .= y; z .= w; x \ carrier L; y \ carrier L; z \ carrier L; w \ carrier L \ \ - x \ z \ y \ w" - -definition - lless :: "[_, 'a, 'a] => bool" (infixl "\\" 50) - where "x \\<^bsub>L\<^esub> y \ x \\<^bsub>L\<^esub> y & x .\\<^bsub>L\<^esub> y" - - -subsubsection \The order relation\ - -context weak_partial_order +imports Order begin -lemma le_cong_l [intro, trans]: - "\ x .= y; y \ z; x \ carrier L; y \ carrier L; z \ carrier L \ \ x \ z" - by (auto intro: le_cong [THEN iffD2]) - -lemma le_cong_r [intro, trans]: - "\ x \ y; y .= z; x \ carrier L; y \ carrier L; z \ carrier L \ \ x \ z" - by (auto intro: le_cong [THEN iffD1]) - -lemma weak_refl [intro, simp]: "\ x .= y; x \ carrier L; y \ carrier L \ \ x \ y" - by (simp add: le_cong_l) - -end - -lemma weak_llessI: - fixes R (structure) - assumes "x \ y" and "~(x .= y)" - shows "x \ y" - using assms unfolding lless_def by simp - -lemma lless_imp_le: - fixes R (structure) - assumes "x \ y" - shows "x \ y" - using assms unfolding lless_def by simp - -lemma weak_lless_imp_not_eq: - fixes R (structure) - assumes "x \ y" - shows "\ (x .= y)" - using assms unfolding lless_def by simp - -lemma weak_llessE: - fixes R (structure) - assumes p: "x \ y" and e: "\x \ y; \ (x .= y)\ \ P" - shows "P" - using p by (blast dest: lless_imp_le weak_lless_imp_not_eq e) - -lemma (in weak_partial_order) lless_cong_l [trans]: - assumes xx': "x .= x'" - and xy: "x' \ y" - and carr: "x \ carrier L" "x' \ carrier L" "y \ carrier L" - shows "x \ y" - using assms unfolding lless_def by (auto intro: trans sym) - -lemma (in weak_partial_order) lless_cong_r [trans]: - assumes xy: "x \ y" - and yy': "y .= y'" - and carr: "x \ carrier L" "y \ carrier L" "y' \ carrier L" - shows "x \ y'" - using assms unfolding lless_def by (auto intro: trans sym) (*slow*) - - -lemma (in weak_partial_order) lless_antisym: - assumes "a \ carrier L" "b \ carrier L" - and "a \ b" "b \ a" - shows "P" - using assms - by (elim weak_llessE) auto - -lemma (in weak_partial_order) lless_trans [trans]: - assumes "a \ b" "b \ c" - and carr[simp]: "a \ carrier L" "b \ carrier L" "c \ carrier L" - shows "a \ c" - using assms unfolding lless_def by (blast dest: le_trans intro: sym) - - -subsubsection \Upper and lower bounds of a set\ - -definition - Upper :: "[_, 'a set] => 'a set" - where "Upper L A = {u. (ALL x. x \ A \ carrier L --> x \\<^bsub>L\<^esub> u)} \ carrier L" - -definition - Lower :: "[_, 'a set] => 'a set" - where "Lower L A = {l. (ALL x. x \ A \ carrier L --> l \\<^bsub>L\<^esub> x)} \ carrier L" - -lemma Upper_closed [intro!, simp]: - "Upper L A \ carrier L" - by (unfold Upper_def) clarify - -lemma Upper_memD [dest]: - fixes L (structure) - shows "[| u \ Upper L A; x \ A; A \ carrier L |] ==> x \ u \ u \ carrier L" - by (unfold Upper_def) blast - -lemma (in weak_partial_order) Upper_elemD [dest]: - "[| u .\ Upper L A; u \ carrier L; x \ A; A \ carrier L |] ==> x \ u" - unfolding Upper_def elem_def - by (blast dest: sym) - -lemma Upper_memI: - fixes L (structure) - shows "[| !! y. y \ A ==> y \ x; x \ carrier L |] ==> x \ Upper L A" - by (unfold Upper_def) blast - -lemma (in weak_partial_order) Upper_elemI: - "[| !! y. y \ A ==> y \ x; x \ carrier L |] ==> x .\ Upper L A" - unfolding Upper_def by blast - -lemma Upper_antimono: - "A \ B ==> Upper L B \ Upper L A" - by (unfold Upper_def) blast - -lemma (in weak_partial_order) Upper_is_closed [simp]: - "A \ carrier L ==> is_closed (Upper L A)" - by (rule is_closedI) (blast intro: Upper_memI)+ - -lemma (in weak_partial_order) Upper_mem_cong: - assumes a'carr: "a' \ carrier L" and Acarr: "A \ carrier L" - and aa': "a .= a'" - and aelem: "a \ Upper L A" - shows "a' \ Upper L A" -proof (rule Upper_memI[OF _ a'carr]) - fix y - assume yA: "y \ A" - hence "y \ a" by (intro Upper_memD[OF aelem, THEN conjunct1] Acarr) - also note aa' - finally - show "y \ a'" - by (simp add: a'carr subsetD[OF Acarr yA] subsetD[OF Upper_closed aelem]) -qed - -lemma (in weak_partial_order) Upper_cong: - assumes Acarr: "A \ carrier L" and A'carr: "A' \ carrier L" - and AA': "A {.=} A'" - shows "Upper L A = Upper L A'" -unfolding Upper_def -apply rule - apply (rule, clarsimp) defer 1 - apply (rule, clarsimp) defer 1 -proof - - fix x a' - assume carr: "x \ carrier L" "a' \ carrier L" - and a'A': "a' \ A'" - assume aLxCond[rule_format]: "\a. a \ A \ a \ carrier L \ a \ x" - - from AA' and a'A' have "\a\A. a' .= a" by (rule set_eqD2) - from this obtain a - where aA: "a \ A" - and a'a: "a' .= a" - by auto - note [simp] = subsetD[OF Acarr aA] carr - - note a'a - also have "a \ x" by (simp add: aLxCond aA) - finally show "a' \ x" by simp -next - fix x a - assume carr: "x \ carrier L" "a \ carrier L" - and aA: "a \ A" - assume a'LxCond[rule_format]: "\a'. a' \ A' \ a' \ carrier L \ a' \ x" - - from AA' and aA have "\a'\A'. a .= a'" by (rule set_eqD1) - from this obtain a' - where a'A': "a' \ A'" - and aa': "a .= a'" - by auto - note [simp] = subsetD[OF A'carr a'A'] carr - - note aa' - also have "a' \ x" by (simp add: a'LxCond a'A') - finally show "a \ x" by simp -qed - -lemma Lower_closed [intro!, simp]: - "Lower L A \ carrier L" - by (unfold Lower_def) clarify - -lemma Lower_memD [dest]: - fixes L (structure) - shows "[| l \ Lower L A; x \ A; A \ carrier L |] ==> l \ x \ l \ carrier L" - by (unfold Lower_def) blast - -lemma Lower_memI: - fixes L (structure) - shows "[| !! y. y \ A ==> x \ y; x \ carrier L |] ==> x \ Lower L A" - by (unfold Lower_def) blast - -lemma Lower_antimono: - "A \ B ==> Lower L B \ Lower L A" - by (unfold Lower_def) blast - -lemma (in weak_partial_order) Lower_is_closed [simp]: - "A \ carrier L \ is_closed (Lower L A)" - by (rule is_closedI) (blast intro: Lower_memI dest: sym)+ - -lemma (in weak_partial_order) Lower_mem_cong: - assumes a'carr: "a' \ carrier L" and Acarr: "A \ carrier L" - and aa': "a .= a'" - and aelem: "a \ Lower L A" - shows "a' \ Lower L A" -using assms Lower_closed[of L A] -by (intro Lower_memI) (blast intro: le_cong_l[OF aa'[symmetric]]) - -lemma (in weak_partial_order) Lower_cong: - assumes Acarr: "A \ carrier L" and A'carr: "A' \ carrier L" - and AA': "A {.=} A'" - shows "Lower L A = Lower L A'" -unfolding Lower_def -apply rule - apply clarsimp defer 1 - apply clarsimp defer 1 -proof - - fix x a' - assume carr: "x \ carrier L" "a' \ carrier L" - and a'A': "a' \ A'" - assume "\a. a \ A \ a \ carrier L \ x \ a" - hence aLxCond: "\a. \a \ A; a \ carrier L\ \ x \ a" by fast - - from AA' and a'A' have "\a\A. a' .= a" by (rule set_eqD2) - from this obtain a - where aA: "a \ A" - and a'a: "a' .= a" - by auto - - from aA and subsetD[OF Acarr aA] - have "x \ a" by (rule aLxCond) - also note a'a[symmetric] - finally - show "x \ a'" by (simp add: carr subsetD[OF Acarr aA]) -next - fix x a - assume carr: "x \ carrier L" "a \ carrier L" - and aA: "a \ A" - assume "\a'. a' \ A' \ a' \ carrier L \ x \ a'" - hence a'LxCond: "\a'. \a' \ A'; a' \ carrier L\ \ x \ a'" by fast+ - - from AA' and aA have "\a'\A'. a .= a'" by (rule set_eqD1) - from this obtain a' - where a'A': "a' \ A'" - and aa': "a .= a'" - by auto - from a'A' and subsetD[OF A'carr a'A'] - have "x \ a'" by (rule a'LxCond) - also note aa'[symmetric] - finally show "x \ a" by (simp add: carr subsetD[OF A'carr a'A']) -qed - - -subsubsection \Least and greatest, as predicate\ - -definition - least :: "[_, 'a, 'a set] => bool" - where "least L l A \ A \ carrier L & l \ A & (ALL x : A. l \\<^bsub>L\<^esub> x)" - -definition - greatest :: "[_, 'a, 'a set] => bool" - where "greatest L g A \ A \ carrier L & g \ A & (ALL x : A. x \\<^bsub>L\<^esub> g)" - -text (in weak_partial_order) \Could weaken these to @{term "l \ carrier L \ l - .\ A"} and @{term "g \ carrier L \ g .\ A"}.\ - -lemma least_closed [intro, simp]: - "least L l A ==> l \ carrier L" - by (unfold least_def) fast - -lemma least_mem: - "least L l A ==> l \ A" - by (unfold least_def) fast - -lemma (in weak_partial_order) weak_least_unique: - "[| least L x A; least L y A |] ==> x .= y" - by (unfold least_def) blast - -lemma least_le: - fixes L (structure) - shows "[| least L x A; a \ A |] ==> x \ a" - by (unfold least_def) fast - -lemma (in weak_partial_order) least_cong: - "[| x .= x'; x \ carrier L; x' \ carrier L; is_closed A |] ==> least L x A = least L x' A" - by (unfold least_def) (auto dest: sym) - -text (in weak_partial_order) \@{const least} is not congruent in the second parameter for - @{term "A {.=} A'"}\ - -lemma (in weak_partial_order) least_Upper_cong_l: - assumes "x .= x'" - and "x \ carrier L" "x' \ carrier L" - and "A \ carrier L" - shows "least L x (Upper L A) = least L x' (Upper L A)" - apply (rule least_cong) using assms by auto - -lemma (in weak_partial_order) least_Upper_cong_r: - assumes Acarrs: "A \ carrier L" "A' \ carrier L" (* unneccessary with current Upper? *) - and AA': "A {.=} A'" - shows "least L x (Upper L A) = least L x (Upper L A')" -apply (subgoal_tac "Upper L A = Upper L A'", simp) -by (rule Upper_cong) fact+ - -lemma least_UpperI: - fixes L (structure) - assumes above: "!! x. x \ A ==> x \ s" - and below: "!! y. y \ Upper L A ==> s \ y" - and L: "A \ carrier L" "s \ carrier L" - shows "least L s (Upper L A)" -proof - - have "Upper L A \ carrier L" by simp - moreover from above L have "s \ Upper L A" by (simp add: Upper_def) - moreover from below have "ALL x : Upper L A. s \ x" by fast - ultimately show ?thesis by (simp add: least_def) -qed - -lemma least_Upper_above: - fixes L (structure) - shows "[| least L s (Upper L A); x \ A; A \ carrier L |] ==> x \ s" - by (unfold least_def) blast - -lemma greatest_closed [intro, simp]: - "greatest L l A ==> l \ carrier L" - by (unfold greatest_def) fast - -lemma greatest_mem: - "greatest L l A ==> l \ A" - by (unfold greatest_def) fast - -lemma (in weak_partial_order) weak_greatest_unique: - "[| greatest L x A; greatest L y A |] ==> x .= y" - by (unfold greatest_def) blast - -lemma greatest_le: - fixes L (structure) - shows "[| greatest L x A; a \ A |] ==> a \ x" - by (unfold greatest_def) fast - -lemma (in weak_partial_order) greatest_cong: - "[| x .= x'; x \ carrier L; x' \ carrier L; is_closed A |] ==> - greatest L x A = greatest L x' A" - by (unfold greatest_def) (auto dest: sym) - -text (in weak_partial_order) \@{const greatest} is not congruent in the second parameter for - @{term "A {.=} A'"}\ - -lemma (in weak_partial_order) greatest_Lower_cong_l: - assumes "x .= x'" - and "x \ carrier L" "x' \ carrier L" - and "A \ carrier L" (* unneccessary with current Lower *) - shows "greatest L x (Lower L A) = greatest L x' (Lower L A)" - apply (rule greatest_cong) using assms by auto - -lemma (in weak_partial_order) greatest_Lower_cong_r: - assumes Acarrs: "A \ carrier L" "A' \ carrier L" - and AA': "A {.=} A'" - shows "greatest L x (Lower L A) = greatest L x (Lower L A')" -apply (subgoal_tac "Lower L A = Lower L A'", simp) -by (rule Lower_cong) fact+ - -lemma greatest_LowerI: - fixes L (structure) - assumes below: "!! x. x \ A ==> i \ x" - and above: "!! y. y \ Lower L A ==> y \ i" - and L: "A \ carrier L" "i \ carrier L" - shows "greatest L i (Lower L A)" -proof - - have "Lower L A \ carrier L" by simp - moreover from below L have "i \ Lower L A" by (simp add: Lower_def) - moreover from above have "ALL x : Lower L A. x \ i" by fast - ultimately show ?thesis by (simp add: greatest_def) -qed - -lemma greatest_Lower_below: - fixes L (structure) - shows "[| greatest L i (Lower L A); x \ A; A \ carrier L |] ==> i \ x" - by (unfold greatest_def) blast - -text \Supremum and infimum\ +section \Lattices\ + +subsection \Supremum and infimum\ definition sup :: "[_, 'a set] => 'a" ("\\_" [90] 90) @@ -412,6 +22,26 @@ inf :: "[_, 'a set] => 'a" ("\\_" [90] 90) where "\\<^bsub>L\<^esub>A = (SOME x. greatest L x (Lower L A))" +definition supr :: + "('a, 'b) gorder_scheme \ 'c set \ ('c \ 'a) \ 'a " + where "supr L A f = \\<^bsub>L\<^esub>(f ` A)" + +definition infi :: + "('a, 'b) gorder_scheme \ 'c set \ ('c \ 'a) \ 'a " + where "infi L A f = \\<^bsub>L\<^esub>(f ` A)" + +syntax + "_inf1" :: "('a, 'b) gorder_scheme \ pttrns \ 'a \ 'a" ("(3IINF\ _./ _)" [0, 10] 10) + "_inf" :: "('a, 'b) gorder_scheme \ pttrn \ 'c set \ 'a \ 'a" ("(3IINF\ _:_./ _)" [0, 0, 10] 10) + "_sup1" :: "('a, 'b) gorder_scheme \ pttrns \ 'a \ 'a" ("(3SSUP\ _./ _)" [0, 10] 10) + "_sup" :: "('a, 'b) gorder_scheme \ pttrn \ 'c set \ 'a \ 'a" ("(3SSUP\ _:_./ _)" [0, 0, 10] 10) + +translations + "IINF\<^bsub>L\<^esub> x. B" == "CONST infi L CONST UNIV (%x. B)" + "IINF\<^bsub>L\<^esub> x:A. B" == "CONST infi L A (%x. B)" + "SSUP\<^bsub>L\<^esub> x. B" == "CONST supr L CONST UNIV (%x. B)" + "SSUP\<^bsub>L\<^esub> x:A. B" == "CONST supr L A (%x. B)" + definition join :: "[_, 'a, 'a] => 'a" (infixl "\\" 65) where "x \\<^bsub>L\<^esub> y = \\<^bsub>L\<^esub>{x, y}" @@ -420,6 +50,49 @@ meet :: "[_, 'a, 'a] => 'a" (infixl "\\" 70) where "x \\<^bsub>L\<^esub> y = \\<^bsub>L\<^esub>{x, y}" +definition + LFP :: "('a, 'b) gorder_scheme \ ('a \ 'a) \ 'a" ("\\") where + "LFP L f = \\<^bsub>L\<^esub> {u \ carrier L. f u \\<^bsub>L\<^esub> u}" --\least fixed point\ + +definition + GFP:: "('a, 'b) gorder_scheme \ ('a \ 'a) \ 'a" ("\\") where + "GFP L f = \\<^bsub>L\<^esub> {u \ carrier L. u \\<^bsub>L\<^esub> f u}" --\greatest fixed point\ + + +subsection \Dual operators\ + +lemma sup_dual [simp]: + "\\<^bsub>inv_gorder L\<^esub>A = \\<^bsub>L\<^esub>A" + by (simp add: sup_def inf_def) + +lemma inf_dual [simp]: + "\\<^bsub>inv_gorder L\<^esub>A = \\<^bsub>L\<^esub>A" + by (simp add: sup_def inf_def) + +lemma join_dual [simp]: + "p \\<^bsub>inv_gorder L\<^esub> q = p \\<^bsub>L\<^esub> q" + by (simp add:join_def meet_def) + +lemma meet_dual [simp]: + "p \\<^bsub>inv_gorder L\<^esub> q = p \\<^bsub>L\<^esub> q" + by (simp add:join_def meet_def) + +lemma top_dual [simp]: + "\\<^bsub>inv_gorder L\<^esub> = \\<^bsub>L\<^esub>" + by (simp add: top_def bottom_def) + +lemma bottom_dual [simp]: + "\\<^bsub>inv_gorder L\<^esub> = \\<^bsub>L\<^esub>" + by (simp add: top_def bottom_def) + +lemma LFP_dual [simp]: + "LFP (inv_gorder L) f = GFP L f" + by (simp add:LFP_def GFP_def) + +lemma GFP_dual [simp]: + "GFP (inv_gorder L) f = LFP L f" + by (simp add:LFP_def GFP_def) + subsection \Lattices\ @@ -433,6 +106,18 @@ locale weak_lattice = weak_upper_semilattice + weak_lower_semilattice +lemma (in weak_lattice) dual_weak_lattice: + "weak_lattice (inv_gorder L)" +proof - + interpret dual: weak_partial_order "inv_gorder L" + by (metis dual_weak_order) + + show ?thesis + apply (unfold_locales) + apply (simp_all add: inf_of_two_exists sup_of_two_exists) + done +qed + subsubsection \Supremum\ @@ -589,7 +274,7 @@ lemma (in weak_upper_semilattice) finite_sup_insertI: assumes P: "!!l. least L l (Upper L (insert x A)) ==> P l" and xA: "finite A" "x \ carrier L" "A \ carrier L" - shows "P (\(insert x A))" + shows "P (\ (insert x A))" proof (cases "A = {}") case True with P and xA show ?thesis by (simp add: finite_sup_least) @@ -634,6 +319,11 @@ with sub z show "s \ z" by (fast elim: least_le intro: Upper_memI) qed +lemma (in weak_lattice) weak_le_iff_meet: + assumes "x \ carrier L" "y \ carrier L" + shows "x \ y \ (x \ y) .= y" + by (meson assms(1) assms(2) join_closed join_le join_left join_right le_cong_r local.le_refl weak_le_antisym) + lemma (in weak_upper_semilattice) weak_join_assoc_lemma: assumes L: "x \ carrier L" "y \ carrier L" "z \ carrier L" shows "x \ (y \ z) .= \{x, y, z}" @@ -828,7 +518,7 @@ lemma (in weak_lower_semilattice) finite_inf_insertI: assumes P: "!!i. greatest L i (Lower L (insert x A)) ==> P i" and xA: "finite A" "x \ carrier L" "A \ carrier L" - shows "P (\(insert x A))" + shows "P (\ (insert x A))" proof (cases "A = {}") case True with P and xA show ?thesis by (simp add: finite_inf_greatest) @@ -875,6 +565,11 @@ with sub z show "z \ i" by (fast elim: greatest_le intro: Lower_memI) qed +lemma (in weak_lattice) weak_le_iff_join: + assumes "x \ carrier L" "y \ carrier L" + shows "x \ y \ x .= (x \ y)" + by (meson assms(1) assms(2) local.le_refl local.le_trans meet_closed meet_le meet_left meet_right weak_le_antisym weak_refl) + lemma (in weak_lower_semilattice) weak_meet_assoc_lemma: assumes L: "x \ carrier L" "y \ carrier L" "z \ carrier L" shows "x \ (y \ z) .= \{x, y, z}" @@ -904,28 +599,15 @@ proof - (* FIXME: improved simp, see weak_join_assoc above *) have "(x \ y) \ z = z \ (x \ y)" by (simp only: meet_comm) - also from L have "... .= \{z, x, y}" by (simp add: weak_meet_assoc_lemma) - also from L have "... = \{x, y, z}" by (simp add: insert_commute) + also from L have "... .= \ {z, x, y}" by (simp add: weak_meet_assoc_lemma) + also from L have "... = \ {x, y, z}" by (simp add: insert_commute) also from L have "... .= x \ (y \ z)" by (simp add: weak_meet_assoc_lemma [symmetric]) finally show ?thesis by (simp add: L) qed - -subsection \Total Orders\ - -locale weak_total_order = weak_partial_order + - assumes total: "[| x \ carrier L; y \ carrier L |] ==> x \ y | y \ x" - -text \Introduction rule: the usual definition of total order\ - -lemma (in weak_partial_order) weak_total_orderI: - assumes total: "!!x y. [| x \ carrier L; y \ carrier L |] ==> x \ y | y \ x" - shows "weak_total_order L" - by standard (rule total) - text \Total orders are lattices.\ -sublocale weak_total_order < weak?: weak_lattice +sublocale weak_total_order \ weak?: weak_lattice proof fix x y assume L: "x \ carrier L" "y \ carrier L" @@ -969,337 +651,136 @@ qed -subsection \Complete Lattices\ - -locale weak_complete_lattice = weak_lattice + - assumes sup_exists: - "[| A \ carrier L |] ==> EX s. least L s (Upper L A)" - and inf_exists: - "[| A \ carrier L |] ==> EX i. greatest L i (Lower L A)" - -text \Introduction rule: the usual definition of complete lattice\ - -lemma (in weak_partial_order) weak_complete_latticeI: - assumes sup_exists: - "!!A. [| A \ carrier L |] ==> EX s. least L s (Upper L A)" - and inf_exists: - "!!A. [| A \ carrier L |] ==> EX i. greatest L i (Lower L A)" - shows "weak_complete_lattice L" - by standard (auto intro: sup_exists inf_exists) - -definition - top :: "_ => 'a" ("\\") - where "\\<^bsub>L\<^esub> = sup L (carrier L)" - -definition - bottom :: "_ => 'a" ("\\") - where "\\<^bsub>L\<^esub> = inf L (carrier L)" - - -lemma (in weak_complete_lattice) supI: - "[| !!l. least L l (Upper L A) ==> P l; A \ carrier L |] - ==> P (\A)" -proof (unfold sup_def) - assume L: "A \ carrier L" - and P: "!!l. least L l (Upper L A) ==> P l" - with sup_exists obtain s where "least L s (Upper L A)" by blast - with L show "P (SOME l. least L l (Upper L A))" - by (fast intro: someI2 weak_least_unique P) -qed - -lemma (in weak_complete_lattice) sup_closed [simp]: - "A \ carrier L ==> \A \ carrier L" - by (rule supI) simp_all - -lemma (in weak_complete_lattice) top_closed [simp, intro]: - "\ \ carrier L" - by (unfold top_def) simp - -lemma (in weak_complete_lattice) infI: - "[| !!i. greatest L i (Lower L A) ==> P i; A \ carrier L |] - ==> P (\A)" -proof (unfold inf_def) - assume L: "A \ carrier L" - and P: "!!l. greatest L l (Lower L A) ==> P l" - with inf_exists obtain s where "greatest L s (Lower L A)" by blast - with L show "P (SOME l. greatest L l (Lower L A))" - by (fast intro: someI2 weak_greatest_unique P) -qed - -lemma (in weak_complete_lattice) inf_closed [simp]: - "A \ carrier L ==> \A \ carrier L" - by (rule infI) simp_all +subsection \Weak Bounded Lattices\ -lemma (in weak_complete_lattice) bottom_closed [simp, intro]: - "\ \ carrier L" - by (unfold bottom_def) simp - -text \Jacobson: Theorem 8.1\ - -lemma Lower_empty [simp]: - "Lower L {} = carrier L" - by (unfold Lower_def) simp - -lemma Upper_empty [simp]: - "Upper L {} = carrier L" - by (unfold Upper_def) simp - -theorem (in weak_partial_order) weak_complete_lattice_criterion1: - assumes top_exists: "EX g. greatest L g (carrier L)" - and inf_exists: - "!!A. [| A \ carrier L; A ~= {} |] ==> EX i. greatest L i (Lower L A)" - shows "weak_complete_lattice L" -proof (rule weak_complete_latticeI) - from top_exists obtain top where top: "greatest L top (carrier L)" .. - fix A - assume L: "A \ carrier L" - let ?B = "Upper L A" - from L top have "top \ ?B" by (fast intro!: Upper_memI intro: greatest_le) - then have B_non_empty: "?B ~= {}" by fast - have B_L: "?B \ carrier L" by simp - from inf_exists [OF B_L B_non_empty] - obtain b where b_inf_B: "greatest L b (Lower L ?B)" .. - have "least L b (Upper L A)" -apply (rule least_UpperI) - apply (rule greatest_le [where A = "Lower L ?B"]) - apply (rule b_inf_B) - apply (rule Lower_memI) - apply (erule Upper_memD [THEN conjunct1]) - apply assumption - apply (rule L) - apply (fast intro: L [THEN subsetD]) - apply (erule greatest_Lower_below [OF b_inf_B]) - apply simp - apply (rule L) -apply (rule greatest_closed [OF b_inf_B]) -done - then show "EX s. least L s (Upper L A)" .. -next - fix A - assume L: "A \ carrier L" - show "EX i. greatest L i (Lower L A)" - proof (cases "A = {}") - case True then show ?thesis - by (simp add: top_exists) - next - case False with L show ?thesis - by (rule inf_exists) - qed -qed - -(* TODO: prove dual version *) - - -subsection \Orders and Lattices where \eq\ is the Equality\ - -locale partial_order = weak_partial_order + - assumes eq_is_equal: "op .= = op =" +locale weak_bounded_lattice = + weak_lattice + + weak_partial_order_bottom + + weak_partial_order_top begin -declare weak_le_antisym [rule del] +lemma bottom_meet: "x \ carrier L \ \ \ x .= \" + by (metis bottom_least least_def meet_closed meet_left weak_le_antisym) -lemma le_antisym [intro]: - "[| x \ y; y \ x; x \ carrier L; y \ carrier L |] ==> x = y" - using weak_le_antisym unfolding eq_is_equal . +lemma bottom_join: "x \ carrier L \ \ \ x .= x" + by (metis bottom_least join_closed join_le join_right le_refl least_def weak_le_antisym) -lemma lless_eq: - "x \ y \ x \ y & x \ y" - unfolding lless_def by (simp add: eq_is_equal) +lemma bottom_weak_eq: + "\ b \ carrier L; \ x. x \ carrier L \ b \ x \ \ b .= \" + by (metis bottom_closed bottom_lower weak_le_antisym) -lemma lless_asym: - assumes "a \ carrier L" "b \ carrier L" - and "a \ b" "b \ a" - shows "P" - using assms unfolding lless_eq by auto +lemma top_join: "x \ carrier L \ \ \ x .= \" + by (metis join_closed join_left top_closed top_higher weak_le_antisym) + +lemma top_meet: "x \ carrier L \ \ \ x .= x" + by (metis le_refl meet_closed meet_le meet_right top_closed top_higher weak_le_antisym) + +lemma top_weak_eq: "\ t \ carrier L; \ x. x \ carrier L \ x \ t \ \ t .= \" + by (metis top_closed top_higher weak_le_antisym) end - -text \Least and greatest, as predicate\ - -lemma (in partial_order) least_unique: - "[| least L x A; least L y A |] ==> x = y" - using weak_least_unique unfolding eq_is_equal . - -lemma (in partial_order) greatest_unique: - "[| greatest L x A; greatest L y A |] ==> x = y" - using weak_greatest_unique unfolding eq_is_equal . +sublocale weak_bounded_lattice \ weak_partial_order .. -text \Lattices\ +subsection \Lattices where \eq\ is the Equality\ locale upper_semilattice = partial_order + assumes sup_of_two_exists: "[| x \ carrier L; y \ carrier L |] ==> EX s. least L s (Upper L {x, y})" -sublocale upper_semilattice < weak?: weak_upper_semilattice - by standard (rule sup_of_two_exists) +sublocale upper_semilattice \ weak?: weak_upper_semilattice + by unfold_locales (rule sup_of_two_exists) locale lower_semilattice = partial_order + assumes inf_of_two_exists: "[| x \ carrier L; y \ carrier L |] ==> EX s. greatest L s (Lower L {x, y})" -sublocale lower_semilattice < weak?: weak_lower_semilattice - by standard (rule inf_of_two_exists) +sublocale lower_semilattice \ weak?: weak_lower_semilattice + by unfold_locales (rule inf_of_two_exists) locale lattice = upper_semilattice + lower_semilattice - -text \Supremum\ - -declare (in partial_order) weak_sup_of_singleton [simp del] +sublocale lattice \ weak_lattice .. -lemma (in partial_order) sup_of_singleton [simp]: - "x \ carrier L ==> \{x} = x" - using weak_sup_of_singleton unfolding eq_is_equal . - -lemma (in upper_semilattice) join_assoc_lemma: - assumes L: "x \ carrier L" "y \ carrier L" "z \ carrier L" - shows "x \ (y \ z) = \{x, y, z}" - using weak_join_assoc_lemma L unfolding eq_is_equal . +lemma (in lattice) dual_lattice: + "lattice (inv_gorder L)" +proof - + interpret dual: weak_lattice "inv_gorder L" + by (metis dual_weak_lattice) -lemma (in upper_semilattice) join_assoc: - assumes L: "x \ carrier L" "y \ carrier L" "z \ carrier L" - shows "(x \ y) \ z = x \ (y \ z)" - using weak_join_assoc L unfolding eq_is_equal . - - -text \Infimum\ + show ?thesis + apply (unfold_locales) + apply (simp_all add: inf_of_two_exists sup_of_two_exists) + apply (simp add:eq_is_equal) + done +qed + +lemma (in lattice) le_iff_join: + assumes "x \ carrier L" "y \ carrier L" + shows "x \ y \ x = (x \ y)" + by (simp add: assms(1) assms(2) eq_is_equal weak_le_iff_join) -declare (in partial_order) weak_inf_of_singleton [simp del] +lemma (in lattice) le_iff_meet: + assumes "x \ carrier L" "y \ carrier L" + shows "x \ y \ (x \ y) = y" + by (simp add: assms(1) assms(2) eq_is_equal weak_le_iff_meet) -lemma (in partial_order) inf_of_singleton [simp]: - "x \ carrier L ==> \{x} = x" - using weak_inf_of_singleton unfolding eq_is_equal . - -text \Condition on \A\: infimum exists.\ +text \ Total orders are lattices. \ -lemma (in lower_semilattice) meet_assoc_lemma: - assumes L: "x \ carrier L" "y \ carrier L" "z \ carrier L" - shows "x \ (y \ z) = \{x, y, z}" - using weak_meet_assoc_lemma L unfolding eq_is_equal . +sublocale total_order \ weak?: lattice + by standard (auto intro: weak.weak.sup_of_two_exists weak.weak.inf_of_two_exists) + +text \Functions that preserve joins and meets\ + +definition join_pres :: "('a, 'c) gorder_scheme \ ('b, 'd) gorder_scheme \ ('a \ 'b) \ bool" where +"join_pres X Y f \ lattice X \ lattice Y \ (\ x \ carrier X. \ y \ carrier X. f (x \\<^bsub>X\<^esub> y) = f x \\<^bsub>Y\<^esub> f y)" -lemma (in lower_semilattice) meet_assoc: - assumes L: "x \ carrier L" "y \ carrier L" "z \ carrier L" - shows "(x \ y) \ z = x \ (y \ z)" - using weak_meet_assoc L unfolding eq_is_equal . - - -text \Total Orders\ +definition meet_pres :: "('a, 'c) gorder_scheme \ ('b, 'd) gorder_scheme \ ('a \ 'b) \ bool" where +"meet_pres X Y f \ lattice X \ lattice Y \ (\ x \ carrier X. \ y \ carrier X. f (x \\<^bsub>X\<^esub> y) = f x \\<^bsub>Y\<^esub> f y)" -locale total_order = partial_order + - assumes total_order_total: "[| x \ carrier L; y \ carrier L |] ==> x \ y | y \ x" - -sublocale total_order < weak?: weak_total_order - by standard (rule total_order_total) - -text \Introduction rule: the usual definition of total order\ +lemma join_pres_isotone: + assumes "f \ carrier X \ carrier Y" "join_pres X Y f" + shows "isotone X Y f" + using assms + apply (rule_tac isotoneI) + apply (auto simp add: join_pres_def lattice.le_iff_meet funcset_carrier) + using lattice_def partial_order_def upper_semilattice_def apply blast + using lattice_def partial_order_def upper_semilattice_def apply blast + apply fastforce +done -lemma (in partial_order) total_orderI: - assumes total: "!!x y. [| x \ carrier L; y \ carrier L |] ==> x \ y | y \ x" - shows "total_order L" - by standard (rule total) - -text \Total orders are lattices.\ - -sublocale total_order < weak?: lattice - by standard (auto intro: sup_of_two_exists inf_of_two_exists) +lemma meet_pres_isotone: + assumes "f \ carrier X \ carrier Y" "meet_pres X Y f" + shows "isotone X Y f" + using assms + apply (rule_tac isotoneI) + apply (auto simp add: meet_pres_def lattice.le_iff_join funcset_carrier) + using lattice_def partial_order_def upper_semilattice_def apply blast + using lattice_def partial_order_def upper_semilattice_def apply blast + apply fastforce +done -text \Complete lattices\ - -locale complete_lattice = lattice + - assumes sup_exists: - "[| A \ carrier L |] ==> EX s. least L s (Upper L A)" - and inf_exists: - "[| A \ carrier L |] ==> EX i. greatest L i (Lower L A)" +subsection \Bounded Lattices\ -sublocale complete_lattice < weak?: weak_complete_lattice - by standard (auto intro: sup_exists inf_exists) - -text \Introduction rule: the usual definition of complete lattice\ +locale bounded_lattice = + lattice + + weak_partial_order_bottom + + weak_partial_order_top -lemma (in partial_order) complete_latticeI: - assumes sup_exists: - "!!A. [| A \ carrier L |] ==> EX s. least L s (Upper L A)" - and inf_exists: - "!!A. [| A \ carrier L |] ==> EX i. greatest L i (Lower L A)" - shows "complete_lattice L" - by standard (auto intro: sup_exists inf_exists) +sublocale bounded_lattice \ weak_bounded_lattice .. -theorem (in partial_order) complete_lattice_criterion1: - assumes top_exists: "EX g. greatest L g (carrier L)" - and inf_exists: - "!!A. [| A \ carrier L; A ~= {} |] ==> EX i. greatest L i (Lower L A)" - shows "complete_lattice L" -proof (rule complete_latticeI) - from top_exists obtain top where top: "greatest L top (carrier L)" .. - fix A - assume L: "A \ carrier L" - let ?B = "Upper L A" - from L top have "top \ ?B" by (fast intro!: Upper_memI intro: greatest_le) - then have B_non_empty: "?B ~= {}" by fast - have B_L: "?B \ carrier L" by simp - from inf_exists [OF B_L B_non_empty] - obtain b where b_inf_B: "greatest L b (Lower L ?B)" .. - have "least L b (Upper L A)" -apply (rule least_UpperI) - apply (rule greatest_le [where A = "Lower L ?B"]) - apply (rule b_inf_B) - apply (rule Lower_memI) - apply (erule Upper_memD [THEN conjunct1]) - apply assumption - apply (rule L) - apply (fast intro: L [THEN subsetD]) - apply (erule greatest_Lower_below [OF b_inf_B]) - apply simp - apply (rule L) -apply (rule greatest_closed [OF b_inf_B]) -done - then show "EX s. least L s (Upper L A)" .. -next - fix A - assume L: "A \ carrier L" - show "EX i. greatest L i (Lower L A)" - proof (cases "A = {}") - case True then show ?thesis - by (simp add: top_exists) - next - case False with L show ?thesis - by (rule inf_exists) - qed -qed +context bounded_lattice +begin -(* TODO: prove dual version *) - - -subsection \Examples\ - -subsubsection \The Powerset of a Set is a Complete Lattice\ +lemma bottom_eq: + "\ b \ carrier L; \ x. x \ carrier L \ b \ x \ \ b = \" + by (metis bottom_closed bottom_lower le_antisym) -theorem powerset_is_complete_lattice: - "complete_lattice \carrier = Pow A, eq = op =, le = op \\" - (is "complete_lattice ?L") -proof (rule partial_order.complete_latticeI) - show "partial_order ?L" - by standard auto -next - fix B - assume "B \ carrier ?L" - then have "least ?L (\B) (Upper ?L B)" - by (fastforce intro!: least_UpperI simp: Upper_def) - then show "EX s. least ?L s (Upper ?L B)" .. -next - fix B - assume "B \ carrier ?L" - then have "greatest ?L (\B \ A) (Lower ?L B)" - txt \@{term "\B"} is not the infimum of @{term B}: - @{term "\{} = UNIV"} which is in general bigger than @{term "A"}!\ - by (fastforce intro!: greatest_LowerI simp: Lower_def) - then show "EX i. greatest ?L i (Lower ?L B)" .. -qed - -text \An other example, that of the lattice of subgroups of a group, - can be found in Group theory (Section~\ref{sec:subgroup-lattice}).\ +lemma top_eq: "\ t \ carrier L; \ x. x \ carrier L \ x \ t \ \ t = \" + by (metis le_antisym top_closed top_higher) end + +end diff -r b47ba1778e44 -r 30d0b2f1df76 src/HOL/Algebra/Order.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Algebra/Order.thy Thu Mar 02 21:16:02 2017 +0100 @@ -0,0 +1,738 @@ +(* Title: HOL/Algebra/Order.thy + Author: Clemens Ballarin, started 7 November 2003 + Copyright: Clemens Ballarin + +Most congruence rules by Stephan Hohe. +With additional contributions from Alasdair Armstrong and Simon Foster. +*) + +theory Order +imports + "~~/src/HOL/Library/FuncSet" + Congruence +begin + +section \Orders\ + +subsection \Partial Orders\ + +record 'a gorder = "'a eq_object" + + le :: "['a, 'a] => bool" (infixl "\\" 50) + +abbreviation inv_gorder :: "_ \ 'a gorder" where + "inv_gorder L \ + \ carrier = carrier L, + eq = op .=\<^bsub>L\<^esub>, + le = (\ x y. y \\<^bsub>L \<^esub>x) \" + +lemma inv_gorder_inv: + "inv_gorder (inv_gorder L) = L" + by simp + +locale weak_partial_order = equivalence L for L (structure) + + assumes le_refl [intro, simp]: + "x \ carrier L ==> x \ x" + and weak_le_antisym [intro]: + "[| x \ y; y \ x; x \ carrier L; y \ carrier L |] ==> x .= y" + and le_trans [trans]: + "[| x \ y; y \ z; x \ carrier L; y \ carrier L; z \ carrier L |] ==> x \ z" + and le_cong: + "\ x .= y; z .= w; x \ carrier L; y \ carrier L; z \ carrier L; w \ carrier L \ \ + x \ z \ y \ w" + +definition + lless :: "[_, 'a, 'a] => bool" (infixl "\\" 50) + where "x \\<^bsub>L\<^esub> y \ x \\<^bsub>L\<^esub> y & x .\\<^bsub>L\<^esub> y" + + +subsubsection \The order relation\ + +context weak_partial_order +begin + +lemma le_cong_l [intro, trans]: + "\ x .= y; y \ z; x \ carrier L; y \ carrier L; z \ carrier L \ \ x \ z" + by (auto intro: le_cong [THEN iffD2]) + +lemma le_cong_r [intro, trans]: + "\ x \ y; y .= z; x \ carrier L; y \ carrier L; z \ carrier L \ \ x \ z" + by (auto intro: le_cong [THEN iffD1]) + +lemma weak_refl [intro, simp]: "\ x .= y; x \ carrier L; y \ carrier L \ \ x \ y" + by (simp add: le_cong_l) + +end + +lemma weak_llessI: + fixes R (structure) + assumes "x \ y" and "~(x .= y)" + shows "x \ y" + using assms unfolding lless_def by simp + +lemma lless_imp_le: + fixes R (structure) + assumes "x \ y" + shows "x \ y" + using assms unfolding lless_def by simp + +lemma weak_lless_imp_not_eq: + fixes R (structure) + assumes "x \ y" + shows "\ (x .= y)" + using assms unfolding lless_def by simp + +lemma weak_llessE: + fixes R (structure) + assumes p: "x \ y" and e: "\x \ y; \ (x .= y)\ \ P" + shows "P" + using p by (blast dest: lless_imp_le weak_lless_imp_not_eq e) + +lemma (in weak_partial_order) lless_cong_l [trans]: + assumes xx': "x .= x'" + and xy: "x' \ y" + and carr: "x \ carrier L" "x' \ carrier L" "y \ carrier L" + shows "x \ y" + using assms unfolding lless_def by (auto intro: trans sym) + +lemma (in weak_partial_order) lless_cong_r [trans]: + assumes xy: "x \ y" + and yy': "y .= y'" + and carr: "x \ carrier L" "y \ carrier L" "y' \ carrier L" + shows "x \ y'" + using assms unfolding lless_def by (auto intro: trans sym) (*slow*) + + +lemma (in weak_partial_order) lless_antisym: + assumes "a \ carrier L" "b \ carrier L" + and "a \ b" "b \ a" + shows "P" + using assms + by (elim weak_llessE) auto + +lemma (in weak_partial_order) lless_trans [trans]: + assumes "a \ b" "b \ c" + and carr[simp]: "a \ carrier L" "b \ carrier L" "c \ carrier L" + shows "a \ c" + using assms unfolding lless_def by (blast dest: le_trans intro: sym) + +lemma weak_partial_order_subset: + assumes "weak_partial_order L" "A \ carrier L" + shows "weak_partial_order (L\ carrier := A \)" +proof - + interpret L: weak_partial_order L + by (simp add: assms) + interpret equivalence "(L\ carrier := A \)" + by (simp add: L.equivalence_axioms assms(2) equivalence_subset) + show ?thesis + apply (unfold_locales, simp_all) + using assms(2) apply auto[1] + using assms(2) apply auto[1] + apply (meson L.le_trans assms(2) contra_subsetD) + apply (meson L.le_cong assms(2) subsetCE) + done +qed + + +subsubsection \Upper and lower bounds of a set\ + +definition + Upper :: "[_, 'a set] => 'a set" + where "Upper L A = {u. (ALL x. x \ A \ carrier L --> x \\<^bsub>L\<^esub> u)} \ carrier L" + +definition + Lower :: "[_, 'a set] => 'a set" + where "Lower L A = {l. (ALL x. x \ A \ carrier L --> l \\<^bsub>L\<^esub> x)} \ carrier L" + +lemma Upper_closed [intro!, simp]: + "Upper L A \ carrier L" + by (unfold Upper_def) clarify + +lemma Upper_memD [dest]: + fixes L (structure) + shows "[| u \ Upper L A; x \ A; A \ carrier L |] ==> x \ u \ u \ carrier L" + by (unfold Upper_def) blast + +lemma (in weak_partial_order) Upper_elemD [dest]: + "[| u .\ Upper L A; u \ carrier L; x \ A; A \ carrier L |] ==> x \ u" + unfolding Upper_def elem_def + by (blast dest: sym) + +lemma Upper_memI: + fixes L (structure) + shows "[| !! y. y \ A ==> y \ x; x \ carrier L |] ==> x \ Upper L A" + by (unfold Upper_def) blast + +lemma (in weak_partial_order) Upper_elemI: + "[| !! y. y \ A ==> y \ x; x \ carrier L |] ==> x .\ Upper L A" + unfolding Upper_def by blast + +lemma Upper_antimono: + "A \ B ==> Upper L B \ Upper L A" + by (unfold Upper_def) blast + +lemma (in weak_partial_order) Upper_is_closed [simp]: + "A \ carrier L ==> is_closed (Upper L A)" + by (rule is_closedI) (blast intro: Upper_memI)+ + +lemma (in weak_partial_order) Upper_mem_cong: + assumes a'carr: "a' \ carrier L" and Acarr: "A \ carrier L" + and aa': "a .= a'" + and aelem: "a \ Upper L A" + shows "a' \ Upper L A" +proof (rule Upper_memI[OF _ a'carr]) + fix y + assume yA: "y \ A" + hence "y \ a" by (intro Upper_memD[OF aelem, THEN conjunct1] Acarr) + also note aa' + finally + show "y \ a'" + by (simp add: a'carr subsetD[OF Acarr yA] subsetD[OF Upper_closed aelem]) +qed + +lemma (in weak_partial_order) Upper_cong: + assumes Acarr: "A \ carrier L" and A'carr: "A' \ carrier L" + and AA': "A {.=} A'" + shows "Upper L A = Upper L A'" +unfolding Upper_def +apply rule + apply (rule, clarsimp) defer 1 + apply (rule, clarsimp) defer 1 +proof - + fix x a' + assume carr: "x \ carrier L" "a' \ carrier L" + and a'A': "a' \ A'" + assume aLxCond[rule_format]: "\a. a \ A \ a \ carrier L \ a \ x" + + from AA' and a'A' have "\a\A. a' .= a" by (rule set_eqD2) + from this obtain a + where aA: "a \ A" + and a'a: "a' .= a" + by auto + note [simp] = subsetD[OF Acarr aA] carr + + note a'a + also have "a \ x" by (simp add: aLxCond aA) + finally show "a' \ x" by simp +next + fix x a + assume carr: "x \ carrier L" "a \ carrier L" + and aA: "a \ A" + assume a'LxCond[rule_format]: "\a'. a' \ A' \ a' \ carrier L \ a' \ x" + + from AA' and aA have "\a'\A'. a .= a'" by (rule set_eqD1) + from this obtain a' + where a'A': "a' \ A'" + and aa': "a .= a'" + by auto + note [simp] = subsetD[OF A'carr a'A'] carr + + note aa' + also have "a' \ x" by (simp add: a'LxCond a'A') + finally show "a \ x" by simp +qed + +lemma Lower_closed [intro!, simp]: + "Lower L A \ carrier L" + by (unfold Lower_def) clarify + +lemma Lower_memD [dest]: + fixes L (structure) + shows "[| l \ Lower L A; x \ A; A \ carrier L |] ==> l \ x \ l \ carrier L" + by (unfold Lower_def) blast + +lemma Lower_memI: + fixes L (structure) + shows "[| !! y. y \ A ==> x \ y; x \ carrier L |] ==> x \ Lower L A" + by (unfold Lower_def) blast + +lemma Lower_antimono: + "A \ B ==> Lower L B \ Lower L A" + by (unfold Lower_def) blast + +lemma (in weak_partial_order) Lower_is_closed [simp]: + "A \ carrier L \ is_closed (Lower L A)" + by (rule is_closedI) (blast intro: Lower_memI dest: sym)+ + +lemma (in weak_partial_order) Lower_mem_cong: + assumes a'carr: "a' \ carrier L" and Acarr: "A \ carrier L" + and aa': "a .= a'" + and aelem: "a \ Lower L A" + shows "a' \ Lower L A" +using assms Lower_closed[of L A] +by (intro Lower_memI) (blast intro: le_cong_l[OF aa'[symmetric]]) + +lemma (in weak_partial_order) Lower_cong: + assumes Acarr: "A \ carrier L" and A'carr: "A' \ carrier L" + and AA': "A {.=} A'" + shows "Lower L A = Lower L A'" +unfolding Lower_def +apply rule + apply clarsimp defer 1 + apply clarsimp defer 1 +proof - + fix x a' + assume carr: "x \ carrier L" "a' \ carrier L" + and a'A': "a' \ A'" + assume "\a. a \ A \ a \ carrier L \ x \ a" + hence aLxCond: "\a. \a \ A; a \ carrier L\ \ x \ a" by fast + + from AA' and a'A' have "\a\A. a' .= a" by (rule set_eqD2) + from this obtain a + where aA: "a \ A" + and a'a: "a' .= a" + by auto + + from aA and subsetD[OF Acarr aA] + have "x \ a" by (rule aLxCond) + also note a'a[symmetric] + finally + show "x \ a'" by (simp add: carr subsetD[OF Acarr aA]) +next + fix x a + assume carr: "x \ carrier L" "a \ carrier L" + and aA: "a \ A" + assume "\a'. a' \ A' \ a' \ carrier L \ x \ a'" + hence a'LxCond: "\a'. \a' \ A'; a' \ carrier L\ \ x \ a'" by fast+ + + from AA' and aA have "\a'\A'. a .= a'" by (rule set_eqD1) + from this obtain a' + where a'A': "a' \ A'" + and aa': "a .= a'" + by auto + from a'A' and subsetD[OF A'carr a'A'] + have "x \ a'" by (rule a'LxCond) + also note aa'[symmetric] + finally show "x \ a" by (simp add: carr subsetD[OF A'carr a'A']) +qed + +text \Jacobson: Theorem 8.1\ + +lemma Lower_empty [simp]: + "Lower L {} = carrier L" + by (unfold Lower_def) simp + +lemma Upper_empty [simp]: + "Upper L {} = carrier L" + by (unfold Upper_def) simp + + +subsubsection \Least and greatest, as predicate\ + +definition + least :: "[_, 'a, 'a set] => bool" + where "least L l A \ A \ carrier L & l \ A & (ALL x : A. l \\<^bsub>L\<^esub> x)" + +definition + greatest :: "[_, 'a, 'a set] => bool" + where "greatest L g A \ A \ carrier L & g \ A & (ALL x : A. x \\<^bsub>L\<^esub> g)" + +text (in weak_partial_order) \Could weaken these to @{term "l \ carrier L \ l + .\ A"} and @{term "g \ carrier L \ g .\ A"}.\ + +lemma least_closed [intro, simp]: + "least L l A ==> l \ carrier L" + by (unfold least_def) fast + +lemma least_mem: + "least L l A ==> l \ A" + by (unfold least_def) fast + +lemma (in weak_partial_order) weak_least_unique: + "[| least L x A; least L y A |] ==> x .= y" + by (unfold least_def) blast + +lemma least_le: + fixes L (structure) + shows "[| least L x A; a \ A |] ==> x \ a" + by (unfold least_def) fast + +lemma (in weak_partial_order) least_cong: + "[| x .= x'; x \ carrier L; x' \ carrier L; is_closed A |] ==> least L x A = least L x' A" + by (unfold least_def) (auto dest: sym) + +abbreviation is_lub :: "[_, 'a, 'a set] => bool" +where "is_lub L x A \ least L x (Upper L A)" + +text (in weak_partial_order) \@{const least} is not congruent in the second parameter for + @{term "A {.=} A'"}\ + +lemma (in weak_partial_order) least_Upper_cong_l: + assumes "x .= x'" + and "x \ carrier L" "x' \ carrier L" + and "A \ carrier L" + shows "least L x (Upper L A) = least L x' (Upper L A)" + apply (rule least_cong) using assms by auto + +lemma (in weak_partial_order) least_Upper_cong_r: + assumes Acarrs: "A \ carrier L" "A' \ carrier L" (* unneccessary with current Upper? *) + and AA': "A {.=} A'" + shows "least L x (Upper L A) = least L x (Upper L A')" +apply (subgoal_tac "Upper L A = Upper L A'", simp) +by (rule Upper_cong) fact+ + +lemma least_UpperI: + fixes L (structure) + assumes above: "!! x. x \ A ==> x \ s" + and below: "!! y. y \ Upper L A ==> s \ y" + and L: "A \ carrier L" "s \ carrier L" + shows "least L s (Upper L A)" +proof - + have "Upper L A \ carrier L" by simp + moreover from above L have "s \ Upper L A" by (simp add: Upper_def) + moreover from below have "ALL x : Upper L A. s \ x" by fast + ultimately show ?thesis by (simp add: least_def) +qed + +lemma least_Upper_above: + fixes L (structure) + shows "[| least L s (Upper L A); x \ A; A \ carrier L |] ==> x \ s" + by (unfold least_def) blast + +lemma greatest_closed [intro, simp]: + "greatest L l A ==> l \ carrier L" + by (unfold greatest_def) fast + +lemma greatest_mem: + "greatest L l A ==> l \ A" + by (unfold greatest_def) fast + +lemma (in weak_partial_order) weak_greatest_unique: + "[| greatest L x A; greatest L y A |] ==> x .= y" + by (unfold greatest_def) blast + +lemma greatest_le: + fixes L (structure) + shows "[| greatest L x A; a \ A |] ==> a \ x" + by (unfold greatest_def) fast + +lemma (in weak_partial_order) greatest_cong: + "[| x .= x'; x \ carrier L; x' \ carrier L; is_closed A |] ==> + greatest L x A = greatest L x' A" + by (unfold greatest_def) (auto dest: sym) + +abbreviation is_glb :: "[_, 'a, 'a set] => bool" +where "is_glb L x A \ greatest L x (Lower L A)" + +text (in weak_partial_order) \@{const greatest} is not congruent in the second parameter for + @{term "A {.=} A'"} \ + +lemma (in weak_partial_order) greatest_Lower_cong_l: + assumes "x .= x'" + and "x \ carrier L" "x' \ carrier L" + and "A \ carrier L" (* unneccessary with current Lower *) + shows "greatest L x (Lower L A) = greatest L x' (Lower L A)" + apply (rule greatest_cong) using assms by auto + +lemma (in weak_partial_order) greatest_Lower_cong_r: + assumes Acarrs: "A \ carrier L" "A' \ carrier L" + and AA': "A {.=} A'" + shows "greatest L x (Lower L A) = greatest L x (Lower L A')" +apply (subgoal_tac "Lower L A = Lower L A'", simp) +by (rule Lower_cong) fact+ + +lemma greatest_LowerI: + fixes L (structure) + assumes below: "!! x. x \ A ==> i \ x" + and above: "!! y. y \ Lower L A ==> y \ i" + and L: "A \ carrier L" "i \ carrier L" + shows "greatest L i (Lower L A)" +proof - + have "Lower L A \ carrier L" by simp + moreover from below L have "i \ Lower L A" by (simp add: Lower_def) + moreover from above have "ALL x : Lower L A. x \ i" by fast + ultimately show ?thesis by (simp add: greatest_def) +qed + +lemma greatest_Lower_below: + fixes L (structure) + shows "[| greatest L i (Lower L A); x \ A; A \ carrier L |] ==> i \ x" + by (unfold greatest_def) blast + +lemma Lower_dual [simp]: + "Lower (inv_gorder L) A = Upper L A" + by (simp add:Upper_def Lower_def) + +lemma Upper_dual [simp]: + "Upper (inv_gorder L) A = Lower L A" + by (simp add:Upper_def Lower_def) + +lemma least_dual [simp]: + "least (inv_gorder L) x A = greatest L x A" + by (simp add:least_def greatest_def) + +lemma greatest_dual [simp]: + "greatest (inv_gorder L) x A = least L x A" + by (simp add:least_def greatest_def) + +lemma (in weak_partial_order) dual_weak_order: + "weak_partial_order (inv_gorder L)" + apply (unfold_locales) + apply (simp_all) + apply (metis sym) + apply (metis trans) + apply (metis weak_le_antisym) + apply (metis le_trans) + apply (metis le_cong_l le_cong_r sym) +done + +lemma dual_weak_order_iff: + "weak_partial_order (inv_gorder A) \ weak_partial_order A" +proof + assume "weak_partial_order (inv_gorder A)" + then interpret dpo: weak_partial_order "inv_gorder A" + rewrites "carrier (inv_gorder A) = carrier A" + and "le (inv_gorder A) = (\ x y. le A y x)" + and "eq (inv_gorder A) = eq A" + by (simp_all) + show "weak_partial_order A" + by (unfold_locales, auto intro: dpo.sym dpo.trans dpo.le_trans) +next + assume "weak_partial_order A" + thus "weak_partial_order (inv_gorder A)" + by (metis weak_partial_order.dual_weak_order) +qed + + +subsubsection \Intervals\ + +definition + at_least_at_most :: "('a, 'c) gorder_scheme \ 'a => 'a => 'a set" ("(1\_.._\\)") + where "\l..u\\<^bsub>A\<^esub> = {x \ carrier A. l \\<^bsub>A\<^esub> x \ x \\<^bsub>A\<^esub> u}" + +context weak_partial_order +begin + + lemma at_least_at_most_upper [dest]: + "x \ \a..b\ \ x \ b" + by (simp add: at_least_at_most_def) + + lemma at_least_at_most_lower [dest]: + "x \ \a..b\ \ a \ x" + by (simp add: at_least_at_most_def) + + lemma at_least_at_most_closed: "\a..b\ \ carrier L" + by (auto simp add: at_least_at_most_def) + + lemma at_least_at_most_member [intro]: + "\ x \ carrier L; a \ x; x \ b \ \ x \ \a..b\" + by (simp add: at_least_at_most_def) + +end + + +subsubsection \Isotone functions\ + +definition isotone :: "('a, 'c) gorder_scheme \ ('b, 'd) gorder_scheme \ ('a \ 'b) \ bool" + where + "isotone A B f \ + weak_partial_order A \ weak_partial_order B \ + (\x\carrier A. \y\carrier A. x \\<^bsub>A\<^esub> y \ f x \\<^bsub>B\<^esub> f y)" + +lemma isotoneI [intro?]: + fixes f :: "'a \ 'b" + assumes "weak_partial_order L1" + "weak_partial_order L2" + "(\x y. \ x \ carrier L1; y \ carrier L1; x \\<^bsub>L1\<^esub> y \ + \ f x \\<^bsub>L2\<^esub> f y)" + shows "isotone L1 L2 f" + using assms by (auto simp add:isotone_def) + +abbreviation Monotone :: "('a, 'b) gorder_scheme \ ('a \ 'a) \ bool" ("Mono\") + where "Monotone L f \ isotone L L f" + +lemma use_iso1: + "\isotone A A f; x \ carrier A; y \ carrier A; x \\<^bsub>A\<^esub> y\ \ + f x \\<^bsub>A\<^esub> f y" + by (simp add: isotone_def) + +lemma use_iso2: + "\isotone A B f; x \ carrier A; y \ carrier A; x \\<^bsub>A\<^esub> y\ \ + f x \\<^bsub>B\<^esub> f y" + by (simp add: isotone_def) + +lemma iso_compose: + "\f \ carrier A \ carrier B; isotone A B f; g \ carrier B \ carrier C; isotone B C g\ \ + isotone A C (g \ f)" + by (simp add: isotone_def, safe, metis Pi_iff) + +lemma (in weak_partial_order) inv_isotone [simp]: + "isotone (inv_gorder A) (inv_gorder B) f = isotone A B f" + by (auto simp add:isotone_def dual_weak_order dual_weak_order_iff) + + +subsubsection \Idempotent functions\ + +definition idempotent :: + "('a, 'b) gorder_scheme \ ('a \ 'a) \ bool" ("Idem\") where + "idempotent L f \ \x\carrier L. f (f x) .=\<^bsub>L\<^esub> f x" + +lemma (in weak_partial_order) idempotent: + "\ Idem f; x \ carrier L \ \ f (f x) .= f x" + by (auto simp add: idempotent_def) + + +subsubsection \Order embeddings\ + +definition order_emb :: "('a, 'c) gorder_scheme \ ('b, 'd) gorder_scheme \ ('a \ 'b) \ bool" + where + "order_emb A B f \ weak_partial_order A + \ weak_partial_order B + \ (\x\carrier A. \y\carrier A. f x \\<^bsub>B\<^esub> f y \ x \\<^bsub>A\<^esub> y )" + +lemma order_emb_isotone: "order_emb A B f \ isotone A B f" + by (auto simp add: isotone_def order_emb_def) + + +subsubsection \Commuting functions\ + +definition commuting :: "('a, 'c) gorder_scheme \ ('a \ 'a) \ ('a \ 'a) \ bool" where +"commuting A f g = (\x\carrier A. (f \ g) x .=\<^bsub>A\<^esub> (g \ f) x)" + +subsection \Partial orders where \eq\ is the Equality\ + +locale partial_order = weak_partial_order + + assumes eq_is_equal: "op .= = op =" +begin + +declare weak_le_antisym [rule del] + +lemma le_antisym [intro]: + "[| x \ y; y \ x; x \ carrier L; y \ carrier L |] ==> x = y" + using weak_le_antisym unfolding eq_is_equal . + +lemma lless_eq: + "x \ y \ x \ y & x \ y" + unfolding lless_def by (simp add: eq_is_equal) + +lemma set_eq_is_eq: "A {.=} B \ A = B" + by (auto simp add: set_eq_def elem_def eq_is_equal) + +end + +lemma (in partial_order) dual_order: + "partial_order (inv_gorder L)" +proof - + interpret dwo: weak_partial_order "inv_gorder L" + by (metis dual_weak_order) + show ?thesis + by (unfold_locales, simp add:eq_is_equal) +qed + +lemma dual_order_iff: + "partial_order (inv_gorder A) \ partial_order A" +proof + assume assm:"partial_order (inv_gorder A)" + then interpret po: partial_order "inv_gorder A" + rewrites "carrier (inv_gorder A) = carrier A" + and "le (inv_gorder A) = (\ x y. le A y x)" + and "eq (inv_gorder A) = eq A" + by (simp_all) + show "partial_order A" + apply (unfold_locales, simp_all) + apply (metis po.sym, metis po.trans) + apply (metis po.weak_le_antisym, metis po.le_trans) + apply (metis (full_types) po.eq_is_equal, metis po.eq_is_equal) + done +next + assume "partial_order A" + thus "partial_order (inv_gorder A)" + by (metis partial_order.dual_order) +qed + +text \Least and greatest, as predicate\ + +lemma (in partial_order) least_unique: + "[| least L x A; least L y A |] ==> x = y" + using weak_least_unique unfolding eq_is_equal . + +lemma (in partial_order) greatest_unique: + "[| greatest L x A; greatest L y A |] ==> x = y" + using weak_greatest_unique unfolding eq_is_equal . + + +subsection \Bounded Orders\ + +definition + top :: "_ => 'a" ("\\") where + "\\<^bsub>L\<^esub> = (SOME x. greatest L x (carrier L))" + +definition + bottom :: "_ => 'a" ("\\") where + "\\<^bsub>L\<^esub> = (SOME x. least L x (carrier L))" + +locale weak_partial_order_bottom = weak_partial_order L for L (structure) + + assumes bottom_exists: "\ x. least L x (carrier L)" +begin + +lemma bottom_least: "least L \ (carrier L)" +proof - + obtain x where "least L x (carrier L)" + by (metis bottom_exists) + + thus ?thesis + by (auto intro:someI2 simp add: bottom_def) +qed + +lemma bottom_closed [simp, intro]: + "\ \ carrier L" + by (metis bottom_least least_mem) + +lemma bottom_lower [simp, intro]: + "x \ carrier L \ \ \ x" + by (metis bottom_least least_le) + +end + +locale weak_partial_order_top = weak_partial_order L for L (structure) + + assumes top_exists: "\ x. greatest L x (carrier L)" +begin + +lemma top_greatest: "greatest L \ (carrier L)" +proof - + obtain x where "greatest L x (carrier L)" + by (metis top_exists) + + thus ?thesis + by (auto intro:someI2 simp add: top_def) +qed + +lemma top_closed [simp, intro]: + "\ \ carrier L" + by (metis greatest_mem top_greatest) + +lemma top_higher [simp, intro]: + "x \ carrier L \ x \ \" + by (metis greatest_le top_greatest) + +end + + +subsection \Total Orders\ + +locale weak_total_order = weak_partial_order + + assumes total: "\ x \ carrier L; y \ carrier L \ \ x \ y \ y \ x" + +text \Introduction rule: the usual definition of total order\ + +lemma (in weak_partial_order) weak_total_orderI: + assumes total: "!!x y. \ x \ carrier L; y \ carrier L \ \ x \ y \ y \ x" + shows "weak_total_order L" + by unfold_locales (rule total) + + +subsection \Total orders where \eq\ is the Equality\ + +locale total_order = partial_order + + assumes total_order_total: "\ x \ carrier L; y \ carrier L \ \ x \ y \ y \ x" + +sublocale total_order < weak?: weak_total_order + by unfold_locales (rule total_order_total) + +text \Introduction rule: the usual definition of total order\ + +lemma (in partial_order) total_orderI: + assumes total: "!!x y. \ x \ carrier L; y \ carrier L \ \ x \ y \ y \ x" + shows "total_order L" + by unfold_locales (rule total) + +end diff -r b47ba1778e44 -r 30d0b2f1df76 src/HOL/ROOT --- a/src/HOL/ROOT Fri Mar 03 23:21:24 2017 +0100 +++ b/src/HOL/ROOT Thu Mar 02 21:16:02 2017 +0100 @@ -297,7 +297,9 @@ "~~/src/HOL/Number_Theory/Primes" "~~/src/HOL/Library/Permutation" theories - (*** New development, based on explicit structures ***) + (* Orders and Lattices *) + Galois_Connection (* Knaster-Tarski theorem and Galois connections *) + (* Groups *) FiniteProduct (* Product operator for commutative groups *) Sylow (* Sylow's theorem *)