diff --git a/thys/Order_Lattice_Props/Closure_Operators.thy b/thys/Order_Lattice_Props/Closure_Operators.thy --- a/thys/Order_Lattice_Props/Closure_Operators.thy +++ b/thys/Order_Lattice_Props/Closure_Operators.thy @@ -1,514 +1,516 @@ (* Title: Closure and Co-Closure Operators Author: Georg Struth Maintainer: Georg Struth *) section \Closure and Co-Closure Operators\ theory Closure_Operators imports Galois_Connections begin subsection \Closure Operators\ text \Closure and coclosure operators in orders and complete lattices are defined in this section, and some basic properties are proved. Isabelle infers the appropriate types. Facts are taken mainly from the Compendium of Continuous Lattices~\<^cite>\"GierzHKLMS80"\ and Rosenthal's book on quantales~\<^cite>\"Rosenthal90"\.\ definition clop :: "('a::order \ 'a) \ bool" where "clop f = (id \ f \ mono f \ f \ f \ f)" lemma clop_extensive: "clop f \ id \ f" by (simp add: clop_def) lemma clop_extensive_var: "clop f \ x \ f x" by (simp add: clop_def le_fun_def) lemma clop_iso: "clop f \ mono f" by (simp add: clop_def) lemma clop_iso_var: "clop f \ x \ y \ f x \ f y" by (simp add: clop_def mono_def) lemma clop_idem: "clop f \ f \ f = f" by (simp add: antisym clop_def le_fun_def) lemma clop_Fix_range: "clop f \ (Fix f = range f)" by (simp add: clop_idem retraction_prop_fix) lemma clop_idem_var: "clop f \ f (f x) = f x" by (simp add: clop_idem retraction_prop) lemma clop_Inf_closed_var: fixes f :: "'a::complete_lattice \ 'a" shows "clop f \ f \ Inf \ (`) f = Inf \ (`) f" unfolding clop_def mono_def comp_def le_fun_def by (metis (mono_tags, lifting) antisym id_apply le_INF_iff order_refl) lemma clop_top: fixes f :: "'a::complete_lattice \ 'a" shows "clop f \ f \ = \" by (simp add: clop_extensive_var top.extremum_uniqueI) lemma "clop (f::'a::complete_lattice \ 'a) \ f (\x \ X. f x) = (\x \ X. f x)" (*nitpick*) oops lemma "clop (f::'a::complete_lattice \ 'a) \ f (f x \ f y) = f x \ f y" (*nitpick*) oops lemma "clop (f::'a::complete_lattice \ 'a) \ f \ = \" (*nitpick *) oops lemma "clop (f::'a set \ 'a set) \ f (\x \ X. f x) = (\x \ X. f x)" (*nitpick*) oops lemma "clop (f::'a set \ 'a set) \ f (f x \ f y) = f x \ f y" (*nitpick*) oops lemma "clop (f::'a set \ 'a set) \ f \ = \" (*nitpick *) oops lemma clop_closure: "clop f \ (x \ range f) = (f x = x)" by (simp add: clop_idem retraction_prop) lemma clop_closure_set: "clop f \ range f = Fix f" by (simp add: clop_Fix_range) lemma clop_closure_prop: "(clop::('a::complete_lattice_with_dual\ 'a) \ bool) (Inf \ \)" by (simp add: clop_def mono_def) lemma clop_closure_prop_var: "clop (\x::'a::complete_lattice. \{y. x \ y})" unfolding clop_def comp_def le_fun_def mono_def by (simp add: Inf_lower le_Inf_iff) lemma clop_alt: "(clop f) = (\x y. x \ f y \ f x \ f y)" unfolding clop_def mono_def le_fun_def comp_def id_def by (meson dual_order.refl order_trans) text \Finally it is shown that adjoints in a Galois connection yield closure operators.\ lemma clop_adj: fixes f :: "'a::order \ 'b::order" shows "f \ g \ clop (g \ f)" by (simp add: adj_cancel2 adj_idem2 adj_iso4 clop_def) text \Closure operators are monads for posets, and monads arise from adjunctions. This fact is not formalised at this point. But here is the first step: every function can be decomposed into a surjection followed by an injection.\ definition "surj_on f Y = (\y \ Y. \x. y = f x)" lemma surj_surj_on: "surj f \ surj_on f Y" by (simp add: surjD surj_on_def) lemma fun_surj_inj: "\g h. f = g \ h \ surj_on h (range f) \ inj_on g (range f)" proof- obtain h where a: "\x. f x = h x" by blast then have "surj_on h (range f)" by (metis (mono_tags, lifting) imageE surj_on_def) then show ?thesis unfolding inj_on_def surj_on_def fun_eq_iff using a by auto qed text \Connections between downsets, upsets and closure operators are outlined next.\ lemma preorder_clop: "clop (\::'a::preorder set \ 'a set)" by (simp add: clop_def downset_set_ext downset_set_iso) lemma clop_preorder_aux: "clop f \ (x \ f {y} \ f {x} \ f {y})" by (simp add: clop_alt) lemma clop_preorder: "clop f \ class.preorder (\x y. f {x} \ f {y}) (\x y. f {x} \ f {y})" unfolding clop_def mono_def le_fun_def id_def comp_def by standard (auto simp: subset_not_subset_eq) lemma preorder_clop_dual: "clop (\::'a::preorder_with_dual set \ 'a set)" by (simp add: clop_def upset_set_anti upset_set_ext) text \The closed elements of any closure operator over a complete lattice form an Inf-closed set (a Moore family).\ lemma clop_Inf_closed: fixes f :: "'a::complete_lattice \ 'a" shows "clop f \ Inf_closed_set (Fix f)" unfolding clop_def Inf_closed_set_def mono_def le_fun_def comp_def id_def Fix_def - by (smt Inf_greatest Inf_lower antisym mem_Collect_eq subsetCE) + by (smt (verit) Inf_greatest Inf_lower antisym mem_Collect_eq subsetCE) lemma clop_top_Fix: fixes f :: "'a::complete_lattice \ 'a" shows "clop f \ \ \ Fix f" by (simp add: clop_Fix_range clop_closure clop_top) text \Conversely, every Inf-closed subset of a complete lattice is the set of fixpoints of some closure operator.\ lemma Inf_closed_clop: fixes X :: "'a::complete_lattice set" shows "Inf_closed_set X \ clop (\y. \{x \ X. y \ x})" - by (smt Collect_mono_iff Inf_superset_mono clop_alt dual_order.trans le_Inf_iff mem_Collect_eq) + by (smt (verit) Collect_mono_iff Inf_superset_mono clop_alt dual_order.trans le_Inf_iff mem_Collect_eq) lemma Inf_closed_clop_var: fixes X :: "'a::complete_lattice set" shows "clop f \ \x \ X. x \ range f \ \X \ range f" by (metis Inf_closed_set_def clop_Fix_range clop_Inf_closed subsetI) text \It is well known that downsets and upsets over an ordering form subalgebras of the complete powerset lattice.\ typedef (overloaded) 'a downsets = "range (\::'a::order set \ 'a set)" by fastforce setup_lifting type_definition_downsets typedef (overloaded) 'a upsets = "range (\::'a::order set \ 'a set)" by fastforce setup_lifting type_definition_upsets instantiation downsets :: (order) Inf_lattice begin lift_definition Inf_downsets :: "'a downsets set \ 'a downsets" is "Abs_downsets \ Inf \ (`) Rep_downsets". lift_definition less_eq_downsets :: "'a downsets \ 'a downsets \ bool" is "\X Y. Rep_downsets X \ Rep_downsets Y". lift_definition less_downsets :: "'a downsets \ 'a downsets \ bool" is "\X Y. Rep_downsets X \ Rep_downsets Y". instance apply intro_classes apply (transfer, simp) apply (transfer, blast) apply (simp add: Closure_Operators.less_eq_downsets.abs_eq Rep_downsets_inject) - apply (transfer, smt Abs_downsets_inverse INF_lower Inf_closed_clop_var Rep_downsets image_iff o_def preorder_clop) - by transfer (smt comp_def Abs_downsets_inverse Inf_closed_clop_var Rep_downsets image_iff le_INF_iff preorder_clop) + apply (transfer, smt (verit) Abs_downsets_inverse INF_lower Inf_closed_clop_var Rep_downsets image_iff o_def preorder_clop) + apply (transfer, smt (verit) comp_def Abs_downsets_inverse Inf_closed_clop_var Rep_downsets image_iff le_INF_iff preorder_clop) + done end instantiation upsets :: (order_with_dual) Inf_lattice begin lift_definition Inf_upsets :: "'a upsets set \ 'a upsets" is "Abs_upsets \ Inf \ (`) Rep_upsets". lift_definition less_eq_upsets :: "'a upsets \ 'a upsets \ bool" is "\X Y. Rep_upsets X \ Rep_upsets Y". lift_definition less_upsets :: "'a upsets \ 'a upsets \ bool" is "\X Y. Rep_upsets X \ Rep_upsets Y". instance apply intro_classes apply (transfer, simp) apply (transfer, blast) apply (simp add: Closure_Operators.less_eq_upsets.abs_eq Rep_upsets_inject) - apply (transfer, smt Abs_upsets_inverse Inf_closed_clop_var Inf_lower Rep_upsets comp_apply image_iff preorder_clop_dual) - by transfer (smt comp_def Abs_upsets_inverse Inf_closed_clop_var Inter_iff Rep_upsets image_iff preorder_clop_dual subsetCE subsetI) + apply (transfer, smt (verit) Abs_upsets_inverse Inf_closed_clop_var Inf_lower Rep_upsets comp_apply image_iff preorder_clop_dual) + apply (transfer, smt (verit) comp_def Abs_upsets_inverse Inf_closed_clop_var Inter_iff Rep_upsets image_iff preorder_clop_dual subsetCE subsetI) + done end text \It has already been shown in the section on representations that the map ds, which maps elements of the order to its downset, is an order embedding. However, the duality between the underlying ordering and the lattices of up- and down-closed sets as categories can probably not be expressed, as there is no easy access to contravariant functors. \ subsection \Co-Closure Operators\ text \Next, the co-closure (or kernel) operation satisfies dual laws.\ definition coclop :: "('a::order \ 'a::order) \ bool" where "coclop f = (f \ id \ mono f \ f \ f \ f)" lemma coclop_dual: "(coclop::('a::order_with_dual \ 'a) \ bool) = clop \ \\<^sub>F" unfolding coclop_def clop_def id_def mono_def map_dual_def comp_def fun_eq_iff le_fun_def by (metis invol_dual_var ord_dual) lemma coclop_dual_var: fixes f :: "'a::order_with_dual \ 'a" shows "coclop f = clop (\\<^sub>F f)" by (simp add: coclop_dual) lemma clop_dual: "(clop::('a::order_with_dual \ 'a) \ bool) = coclop \ \\<^sub>F" by (simp add: coclop_dual comp_assoc map_dual_invol) lemma clop_dual_var: fixes f :: "'a::order_with_dual \ 'a" shows "clop f = coclop (\\<^sub>F f)" by (simp add: clop_dual) lemma coclop_coextensive: "coclop f \ f \ id" by (simp add: coclop_def) lemma coclop_coextensive_var: "coclop f \ f x \ x" using coclop_def le_funD by fastforce lemma coclop_iso: "coclop f \ mono f" by (simp add: coclop_def) lemma coclop_iso_var: "coclop f \ (x \ y \ f x \ f y)" by (simp add: coclop_iso monoD) lemma coclop_idem: "coclop f \ f \ f = f" by (simp add: antisym coclop_def le_fun_def) lemma coclop_closure: "coclop f \ (x \ range f) = (f x = x)" by (simp add: coclop_idem retraction_prop) lemma coclop_Fix_range: "coclop f \ (Fix f = range f)" by (simp add: coclop_idem retraction_prop_fix) lemma coclop_idem_var: "coclop f \ f (f x) = f x" by (simp add: coclop_idem retraction_prop) lemma coclop_Sup_closed_var: fixes f :: "'a::complete_lattice_with_dual \ 'a" shows "coclop f \ f \ Sup \ (`) f = Sup \ (`) f" unfolding coclop_def mono_def comp_def le_fun_def by (metis (mono_tags, lifting) SUP_le_iff antisym id_apply order_refl) lemma Sup_closed_coclop_var: fixes X :: "'a::complete_lattice set" shows "coclop f \ \x \ X. x \ range f \ \X \ range f" - by (smt Inf.INF_id_eq Sup.SUP_cong antisym coclop_closure coclop_coextensive_var coclop_iso id_apply mono_SUP) + by (smt (verit) Inf.INF_id_eq Sup.SUP_cong antisym coclop_closure coclop_coextensive_var coclop_iso id_apply mono_SUP) lemma coclop_bot: fixes f :: "'a::complete_lattice_with_dual \ 'a" shows "coclop f \ f \ = \" by (simp add: bot.extremum_uniqueI coclop_coextensive_var) lemma "coclop (f::'a::complete_lattice \ 'a) \ f (\x \ X. f x) = (\x \ X. f x)" (*nitpick*) oops lemma "coclop (f::'a::complete_lattice \ 'a) \ f (f x \ f y) = f x \ f y" (*nitpick*) oops lemma "coclop (f::'a::complete_lattice \ 'a) \ f \ = \" (*nitpick*) oops lemma "coclop (f::'a set \ 'a set) \ f (\x \ X. f x) = (\x \ X. f x)" (*nitpick*) oops lemma "coclop (f::'a set \ 'a set) \ f (f x \ f y) = f x \ f y" (*nitpick*) oops lemma "coclop (f::'a set \ 'a set) \ f \ = \" (*nitpick *) oops lemma coclop_coclosure: "coclop f \ f x = x \ x \ range f" by (simp add: coclop_idem retraction_prop) lemma coclop_coclosure_set: "coclop f \ range f = Fix f" by (simp add: coclop_idem retraction_prop_fix) lemma coclop_coclosure_prop: "(coclop::('a::complete_lattice \ 'a) \ bool) (Sup \ \)" by (simp add: coclop_def mono_def) lemma coclop_coclosure_prop_var: "coclop (\x::'a::complete_lattice. \{y. y \ x})" by (metis (mono_tags, lifting) Sup_atMost atMost_def coclop_def comp_apply eq_id_iff eq_refl mono_def) lemma coclop_alt: "(coclop f) = (\x y. f x \ y \ f x \ f y)" unfolding coclop_def mono_def le_fun_def comp_def id_def by (meson dual_order.refl order_trans) lemma coclop_adj: fixes f :: "'a::order \ 'b::order" shows "f \ g \ coclop (f \ g)" by (simp add: adj_cancel1 adj_idem1 adj_iso3 coclop_def) text \Finally, a subset of a complete lattice is Sup-closed if and only if it is the set of fixpoints of some co-closure operator.\ lemma coclop_Sup_closed: fixes f :: "'a::complete_lattice \ 'a" shows "coclop f \ Sup_closed_set (Fix f)" unfolding coclop_def Sup_closed_set_def mono_def le_fun_def comp_def id_def Fix_def - by (smt Sup_least Sup_upper antisym_conv mem_Collect_eq subsetCE) + by (smt (verit) Sup_least Sup_upper antisym_conv mem_Collect_eq subsetCE) lemma Sup_closed_coclop: fixes X :: "'a::complete_lattice set" shows "Sup_closed_set X \ coclop (\y. \{x \ X. x \ y})" unfolding Sup_closed_set_def coclop_def mono_def le_fun_def comp_def apply safe apply (metis (no_types, lifting) Sup_least eq_id_iff mem_Collect_eq) - apply (smt Collect_mono_iff Sup_subset_mono dual_order.trans) + apply (smt (verit) Collect_mono_iff Sup_subset_mono dual_order.trans) by (simp add: Collect_mono_iff Sup_subset_mono Sup_upper) subsection \Complete Lattices of Closed Elements\ text \The machinery developed allows showing that the closed elements in a complete lattice (with respect to some closure operation) form themselves a complete lattice.\ class cl_op = ord + fixes cl_op :: "'a \ 'a" assumes clop_ext: "x \ cl_op x" and clop_iso: "x \ y \ cl_op x \ cl_op y" and clop_wtrans: "cl_op (cl_op x) \ cl_op x" class clattice_with_clop = complete_lattice + cl_op begin lemma clop_cl_op: "clop cl_op" unfolding clop_def le_fun_def comp_def by (simp add: cl_op_class.clop_ext cl_op_class.clop_iso cl_op_class.clop_wtrans order_class.mono_def) lemma clop_idem [simp]: "cl_op \ cl_op = cl_op" using clop_ext clop_wtrans order.antisym by auto lemma clop_idem_var [simp]: "cl_op (cl_op x) = cl_op x" by (simp add: order.antisym clop_ext clop_wtrans) lemma clop_range_Fix: "range cl_op = Fix cl_op" by (simp add: retraction_prop_fix) lemma Inf_closed_cl_op_var: fixes X :: "'a set" shows "\x \ X. x \ range cl_op \ \X \ range cl_op" proof- assume h: "\x \ X. x \ range cl_op" hence "\x \ X. cl_op x = x" by (simp add: retraction_prop) hence "cl_op (\X) = \X" by (metis Inf_lower clop_ext clop_iso dual_order.antisym le_Inf_iff) thus ?thesis by (metis rangeI) qed lemma inf_closed_cl_op_var: "x \ range cl_op \ y \ range cl_op \ x \ y \ range cl_op" - by (smt Inf_closed_cl_op_var UnI1 insert_iff insert_is_Un inf_Inf) + by (smt (verit) Inf_closed_cl_op_var UnI1 insert_iff insert_is_Un inf_Inf) end typedef (overloaded) 'a::clattice_with_clop cl_op_im = "range (cl_op::'a \ 'a)" by force setup_lifting type_definition_cl_op_im lemma cl_op_prop [iff]: "(cl_op (x \ y) = cl_op y) = (cl_op (x::'a::clattice_with_clop) \ cl_op y)" - by (smt cl_op_class.clop_iso clop_ext clop_wtrans inf_sup_ord(4) le_iff_sup sup.absorb_iff1 sup_left_commute) + by (smt (verit) cl_op_class.clop_iso clop_ext clop_wtrans inf_sup_ord(4) le_iff_sup sup.absorb_iff1 sup_left_commute) lemma cl_op_prop_var [iff]: "(cl_op (x \ cl_op y) = cl_op y) = (cl_op (x::'a::clattice_with_clop) \ cl_op y)" by (metis cl_op_prop clattice_with_clop_class.clop_idem_var) instantiation cl_op_im :: (clattice_with_clop) complete_lattice begin lift_definition Inf_cl_op_im :: "'a cl_op_im set \ 'a cl_op_im" is Inf by (simp add: Inf_closed_cl_op_var) lift_definition Sup_cl_op_im :: "'a cl_op_im set \ 'a cl_op_im" is "\X. cl_op (\X)" by simp lift_definition inf_cl_op_im :: "'a cl_op_im \ 'a cl_op_im \ 'a cl_op_im" is inf by (simp add: inf_closed_cl_op_var) lift_definition sup_cl_op_im :: "'a cl_op_im \ 'a cl_op_im \ 'a cl_op_im" is "\x y. cl_op (x \ y)" by simp lift_definition less_eq_cl_op_im :: "'a cl_op_im \ 'a cl_op_im \ bool" is "(\)". lift_definition less_cl_op_im :: "'a cl_op_im \ 'a cl_op_im \ bool" is "(<)". lift_definition bot_cl_op_im :: "'a cl_op_im" is "cl_op \" by simp lift_definition top_cl_op_im :: "'a cl_op_im" is "\" by (simp add: clop_cl_op clop_closure clop_top) instance apply (intro_classes; transfer) apply (simp_all add: less_le_not_le Inf_lower Inf_greatest) apply (meson clop_cl_op clop_extensive_var dual_order.trans inf_sup_ord(3)) apply (meson clop_cl_op clop_extensive_var dual_order.trans sup_ge2) apply (metis cl_op_class.clop_iso clop_cl_op clop_closure le_sup_iff) apply (meson Sup_upper clop_cl_op clop_extensive_var dual_order.trans) by (metis Sup_le_iff cl_op_class.clop_iso clop_cl_op clop_closure) end text \This statement is perhaps less useful as it might seem, because it is difficult to make it cooperate with concrete closure operators, which one would not generally like to define within a type class. Alternatively, a sublocale statement could perhaps be given. It would also have been nice to prove this statement for Sup-lattices---this would have cut down the number of proof obligations significantly. But this would require a tighter integration of these structures. A similar statement could have been proved for co-closure operators. But this would not lead to new insights.\ text \Next I show that for every surjective Sup-preserving function between complete lattices there is a closure operator such that the set of closed elements is isomorphic to the range of the surjection.\ lemma surj_Sup_pres_id: fixes f :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" assumes "surj f" and "Sup_pres f" shows "f \ (radj f) = id" proof- have "f \ (radj f)" using Sup_pres_ladj assms(2) radj_adj by auto thus ?thesis using adj_sur_inv assms(1) by blast qed lemma surj_Sup_pres_inj: fixes f :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" assumes "surj f" and "Sup_pres f" shows "inj (radj f)" by (metis assms comp_eq_dest_lhs id_apply injI surj_Sup_pres_id) lemma surj_Sup_pres_inj_on: fixes f :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" assumes "surj f" and "Sup_pres f" shows "inj_on f (range (radj f \ f))" - by (smt Sup_pres_ladj_aux adj_idem2 assms(2) comp_apply inj_on_def retraction_prop) + by (smt (verit) Sup_pres_ladj_aux adj_idem2 assms(2) comp_apply inj_on_def retraction_prop) lemma surj_Sup_pres_bij_on: fixes f :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" assumes "surj f" and "Sup_pres f" shows "bij_betw f (range (radj f \ f)) UNIV" unfolding bij_betw_def apply safe apply (simp add: assms(1) assms(2) surj_Sup_pres_inj_on cong del: image_cong_simp) apply auto apply (metis (mono_tags) UNIV_I assms(1) assms(2) comp_apply id_apply image_image surj_Sup_pres_id surj_def) done text \Thus the restriction of $f$ to the set of closed elements is indeed a bijection. The final fact shows that it preserves Sups of closed elements, and hence is an isomorphism of complete lattices.\ lemma surj_Sup_pres_iso: fixes f :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" assumes "surj f" and "Sup_pres f" shows "f ((radj f \ f) (\X)) = (\x \ X. f x)" by (metis assms(1) assms(2) comp_def pointfree_idE surj_Sup_pres_id) subsection \A Quick Example: Dedekind-MacNeille Completions\ text \I only outline the basic construction. Additional facts about join density, and that the completion yields the least complete lattice that contains all Sups and Infs of the underlying posets, are left for future consideration.\ abbreviation "dm \ lb_set \ ub_set" lemma up_set_prop: "(X::'a::preorder set) \ {} \ ub_set X = \{\x |x. x \ X}" unfolding ub_set_def upset_def upset_set_def by (safe, simp_all, blast) lemma lb_set_prop: "(X::'a::preorder set) \ {} \ lb_set X = \{\x |x. x \ X}" unfolding lb_set_def downset_def downset_set_def by (safe, simp_all, blast) lemma dm_downset_var: "dm {x} = \(x::'a::preorder)" unfolding lb_set_def ub_set_def downset_def downset_set_def by (clarsimp, meson order_refl order_trans) lemma dm_downset: "dm \ \ = (\::'a::preorder \ 'a set)" using dm_downset_var fun.map_cong by fastforce lemma dm_inj: "inj ((dm::'a::order set \ 'a set) \ \)" by (simp add: dm_downset downset_inj) lemma "clop (lb_set \ ub_set)" unfolding clop_def lb_set_def ub_set_def apply safe unfolding le_fun_def comp_def id_def mono_def by auto end diff --git a/thys/Order_Lattice_Props/Galois_Connections.thy b/thys/Order_Lattice_Props/Galois_Connections.thy --- a/thys/Order_Lattice_Props/Galois_Connections.thy +++ b/thys/Order_Lattice_Props/Galois_Connections.thy @@ -1,243 +1,243 @@ (* Title: Galois Connections Author: Georg Struth Maintainer: Georg Struth *) section \Galois Connections\ theory Galois_Connections imports Order_Lattice_Props begin subsection \Definitions and Basic Properties\ text \The approach follows the Compendium of Continuous Lattices~\<^cite>\"GierzHKLMS80"\, without attempting completeness. First, left and right adjoints of a Galois connection are defined.\ definition adj :: "('a::ord \ 'b::ord) \ ('b \ 'a) \ bool" (infixl "\" 70) where "(f \ g) = (\x y. (f x \ y) = (x \ g y))" definition "ladj (g::'a::Inf \ 'b::ord) = (\x. \{y. x \ g y})" definition "radj (f::'a::Sup \ 'b::ord) = (\y. \{x. f x \ y})" lemma ladj_radj_dual: fixes f :: "'a::complete_lattice_with_dual \ 'b::ord_with_dual" shows "ladj f x = \ (radj (\\<^sub>F f) (\ x))" proof- have "ladj f x = \ (\(\ ` {y. \ (f y) \ \ x}))" unfolding ladj_def by (metis (no_types, lifting) Collect_cong Inf_dual_var dual_dual_ord dual_iff) also have "... = \ (\{\ y|y. \ (f y) \ \ x})" by (simp add: setcompr_eq_image) ultimately show ?thesis unfolding ladj_def radj_def map_dual_def comp_def - by (smt Collect_cong invol_dual_var) + by (smt (verit) Collect_cong invol_dual_var) qed lemma radj_ladj_dual: fixes f :: "'a::complete_lattice_with_dual \ 'b::ord_with_dual" shows "radj f x = \ (ladj (\\<^sub>F f) (\ x))" by (metis fun_dual5 invol_dual_var ladj_radj_dual map_dual_def) lemma ladj_prop: fixes g :: "'b::Inf \ 'a::ord_with_dual" shows "ladj g = Inf \ (-`) g \ \" unfolding ladj_def vimage_def upset_prop fun_eq_iff comp_def by simp lemma radj_prop: fixes f :: "'b::Sup \ 'a::ord" shows "radj f = Sup \ (-`) f \ \" unfolding radj_def vimage_def downset_prop fun_eq_iff comp_def by simp text \The first set of properties holds without any sort assumptions.\ lemma adj_iso1: "f \ g \ mono f" unfolding adj_def mono_def by (meson dual_order.refl dual_order.trans) lemma adj_iso2: "f \ g \ mono g" unfolding adj_def mono_def by (meson dual_order.refl dual_order.trans) lemma adj_comp: "f \ g \ adj h k \ (f \ h) \ (k \ g)" by (simp add: adj_def) lemma adj_dual: fixes f :: "'a::ord_with_dual \ 'b::ord_with_dual" shows "f \ g = (\\<^sub>F g) \ (\\<^sub>F f)" unfolding adj_def map_dual_def comp_def by (metis (mono_tags, opaque_lifting) dual_dual_ord invol_dual_var) subsection \Properties for (Pre)Orders\ text \The next set of properties holds in preorders or orders.\ lemma adj_cancel1: fixes f :: "'a::preorder \ 'b::ord" shows "f \ g \ f \ g \ id" by (simp add: adj_def le_funI) lemma adj_cancel2: fixes f :: "'a::ord \ 'b::preorder" shows "f \ g \ id \ g \ f" by (simp add: adj_def eq_iff le_funI) lemma adj_prop: fixes f :: "'a::preorder \'a" shows "f \ g \ f \ g \ g \ f" using adj_cancel1 adj_cancel2 order_trans by blast lemma adj_cancel_eq1: fixes f :: "'a::preorder \ 'b::order" shows "f \ g \ f \ g \ f = f" unfolding adj_def comp_def fun_eq_iff by (meson eq_iff order_refl order_trans) lemma adj_cancel_eq2: fixes f :: "'a::order \ 'b::preorder" shows "f \ g \ g \ f \ g = g" unfolding adj_def comp_def fun_eq_iff by (meson eq_iff order_refl order_trans) lemma adj_idem1: fixes f :: "'a::preorder \ 'b::order" shows "f \ g \ (f \ g) \ (f \ g) = f \ g" by (simp add: adj_cancel_eq1 rewriteL_comp_comp) lemma adj_idem2: fixes f :: "'a::order \ 'b::preorder" shows "f \ g \ (g \ f) \ (g \ f) = g \ f" by (simp add: adj_cancel_eq2 rewriteL_comp_comp) lemma adj_iso3: fixes f :: "'a::order \ 'b::order" shows "f \ g \ mono (f \ g)" by (simp add: adj_iso1 adj_iso2 monoD monoI) lemma adj_iso4: fixes f :: "'a::order \ 'b::order" shows "f \ g \ mono (g \ f)" by (simp add: adj_iso1 adj_iso2 monoD monoI) lemma adj_canc1: fixes f :: "'a::order \ 'b::ord" shows "f \ g \ ((f \ g) x = (f \ g) y \ g x = g y)" unfolding adj_def comp_def by (metis eq_iff) lemma adj_canc2: fixes f :: "'a::ord \ 'b::order" shows "f \ g \ ((g \ f) x = (g \ f) y \ f x = f y)" unfolding adj_def comp_def by (metis eq_iff) lemma adj_sur_inv: fixes f :: "'a::preorder \ 'b::order" shows "f \ g \ ((surj f) = (f \ g = id))" unfolding adj_def surj_def comp_def by (metis eq_id_iff eq_iff order_refl order_trans) lemma adj_surj_inj: fixes f :: "'a::order \ 'b::order" shows "f \ g \ ((surj f) = (inj g))" unfolding adj_def inj_def surj_def by (metis eq_iff order_trans) lemma adj_inj_inv: fixes f :: "'a::preorder \ 'b::order" shows "f \ g \ ((inj f) = (g \ f = id))" by (metis adj_cancel_eq1 eq_id_iff inj_def o_apply) lemma adj_inj_surj: fixes f :: "'a::order \ 'b::order" shows "f \ g \ ((inj f) = (surj g))" unfolding adj_def inj_def surj_def by (metis eq_iff order_trans) lemma surj_id_the_inv: "surj f \ g \ f = id \ g = the_inv f" by (metis comp_apply id_apply inj_on_id inj_on_imageI2 surj_fun_eq the_inv_f_f) lemma inj_id_the_inv: "inj f \ f \ g = id \ f = the_inv g" proof - assume a1: "inj f" assume "f \ g = id" hence "\x. the_inv g x = f x" using a1 by (metis (no_types) comp_apply eq_id_iff inj_on_id inj_on_imageI2 the_inv_f_f) thus ?thesis by presburger qed subsection \Properties for Complete Lattices\ text \The next laws state that a function between complete lattices preserves infs if and only if it has a lower adjoint.\ lemma radj_Inf_pres: fixes g :: "'b::complete_lattice \ 'a::complete_lattice" shows "(\f. f \ g) \ Inf_pres g" apply (rule antisym, simp_all add: le_fun_def adj_def, safe) apply (meson INF_greatest Inf_lower dual_order.refl dual_order.trans) by (meson Inf_greatest dual_order.refl le_INF_iff) lemma ladj_Sup_pres: fixes f :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" shows "(\g. f \ g) \ Sup_pres f" using Sup_pres_map_dual_var adj_dual radj_Inf_pres by blast lemma radj_adj: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "f \ g \ g = (radj f)" unfolding adj_def radj_def by (metis (mono_tags, lifting) cSup_eq_maximum eq_iff mem_Collect_eq) lemma ladj_adj: fixes g :: "'b::complete_lattice_with_dual \ 'a::complete_lattice_with_dual" shows "f \ g \ f = (ladj g)" unfolding adj_def ladj_def by (metis (no_types, lifting) cInf_eq_minimum eq_iff mem_Collect_eq) lemma Inf_pres_radj_aux: fixes g :: "'a::complete_lattice \ 'b::complete_lattice" shows "Inf_pres g \ (ladj g) \ g" proof- assume a: "Inf_pres g" {fix x y assume b: "ladj g x \ y" hence "g (ladj g x) \ g y" by (simp add: Inf_subdistl_iso a monoD) hence "\{g y |y. x \ g y} \ g y" by (metis a comp_eq_dest_lhs setcompr_eq_image ladj_def) hence "x \ g y" using dual_order.trans le_Inf_iff by blast hence "ladj g x \ y \ x \ g y" by simp} thus ?thesis unfolding adj_def ladj_def by (meson CollectI Inf_lower) qed lemma Sup_pres_ladj_aux: fixes f :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" shows "Sup_pres f \ f \ (radj f)" by (metis (no_types, opaque_lifting) Inf_pres_radj_aux Sup_pres_map_dual_var adj_dual fun_dual5 map_dual_def radj_adj) lemma Inf_pres_radj: fixes g :: "'b::complete_lattice \ 'a::complete_lattice" shows "Inf_pres g \ (\f. f \ g)" using Inf_pres_radj_aux by fastforce lemma Sup_pres_ladj: fixes f :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" shows "Sup_pres f \ (\g. f \ g)" using Sup_pres_ladj_aux by fastforce lemma Inf_pres_upper_adj_eq: fixes g :: "'b::complete_lattice \ 'a::complete_lattice" shows "(Inf_pres g) = (\f. f \ g)" using radj_Inf_pres Inf_pres_radj by blast lemma Sup_pres_ladj_eq: fixes f :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" shows "(Sup_pres f) = (\g. f \ g)" using Sup_pres_ladj ladj_Sup_pres by blast lemma Sup_downset_adj: "(Sup::'a::complete_lattice set \ 'a) \ \" unfolding adj_def downset_prop Sup_le_iff by force lemma Sup_downset_adj_var: "(Sup (X::'a::complete_lattice set) \ y) = (X \ \y)" using Sup_downset_adj adj_def by auto text \Once again many statements arise by duality, which Isabelle usually picks up.\ end \ No newline at end of file diff --git a/thys/Order_Lattice_Props/Order_Duality.thy b/thys/Order_Lattice_Props/Order_Duality.thy --- a/thys/Order_Lattice_Props/Order_Duality.thy +++ b/thys/Order_Lattice_Props/Order_Duality.thy @@ -1,315 +1,315 @@ (* Title: Ad-Hoc Duality for Orderings and Lattices Author: Georg Struth Maintainer: Georg Struth *) section \Ad-Hoc Duality for Orderings and Lattices\ theory Order_Duality imports Sup_Lattice begin text \This component presents an "explicit" formalisation of order and lattice duality. It augments the data type based one used by Wenzel in his lattice components \<^cite>\"Wenzel"\, and complements the "implicit" formalisation given by locales. It uses a functor dual, supplied within a type class, which is simply a bijection (isomorphism) between types, with the constraint that the dual of a dual object is the original object. In Wenzel's formalisation, by contrast, dual is a bijection, but not idempotent or involutive. In the past, Preoteasa has used a similar approach with Isabelle~\<^cite>\"Preoteasa11b"\.\ text \Duality is such a fundamental concept in order and lattice theory that it probably deserves to be included in the type classes for these objects, as in this section.\ class dual = fixes dual :: "'a \ 'a" ("\") assumes inj_dual: "inj \" and invol_dual [simp]: "\ \ \ = id" text \This type class allows one to define a type dual. It is actually a dependent type for which dual can be instantiated.\ typedef (overloaded) 'a dual = "range (dual::'a::dual \ 'a)" by fastforce setup_lifting type_definition_dual text \At the moment I have no use for this type.\ context dual begin lemma invol_dual_var [simp]: "\ (\ x) = x" by (simp add: pointfree_idE) lemma surj_dual: "surj \" unfolding surj_def by (metis invol_dual_var) lemma bij_dual: "bij \" by (simp add: bij_def inj_dual surj_dual) lemma inj_dual_iff: "(\ x = \ y) = (x = y)" by (meson inj_dual injD) lemma dual_iff: "(\ x = y) = (x = \ y)" by auto lemma the_inv_dual: "the_inv \ = \" by (metis comp_apply id_def invol_dual_var inj_dual surj_dual surj_fun_eq the_inv_f_o_f_id) end text \In boolean algebras, duality is of course De Morgan duality and can be expressed within the language.\ sublocale boolean_algebra \ ba_dual: dual "uminus" by (unfold_locales, simp_all add: inj_def) definition map_dual:: "('a \ 'b) \ 'a::dual \ 'b::dual" ("\\<^sub>F") where "\\<^sub>F f = \ \ f \ \" lemma map_dual_func1: "\\<^sub>F (f \ g) = \\<^sub>F f \ \\<^sub>F g" by (metis (no_types, lifting) comp_assoc comp_id invol_dual map_dual_def) lemma map_dual_func2 [simp]: "\\<^sub>F id = id" by (simp add: map_dual_def) lemma map_dual_nat_iso: "\\<^sub>F f \ \ = \ \ id f" by (simp add: comp_assoc map_dual_def) lemma map_dual_invol [simp]: "\\<^sub>F \ \\<^sub>F = id" unfolding map_dual_def comp_def fun_eq_iff by simp text \Thus map-dual is naturally isomorphic to the identify functor: The function dual is a natural transformation between map-dual and the identity functor, and, because it has a two-sided inverse --- itself, it is a natural isomorphism.\ text \The generic function set-dual provides another natural transformation (see below). Before introducing it, we introduce useful notation for a widely used function.\ abbreviation "\ \ (\x. {x})" lemma eta_inj: "inj \" by simp definition "set_dual = \ \ \" lemma set_dual_prop: "set_dual (\ x) = {x}" by (metis comp_apply dual_iff set_dual_def) text \The next four lemmas show that (functional) image and preimage are functors (on functions). This does not really belong here, but it is useful for what follows. The interaction between duality and (pre)images is needed in applications.\ lemma image_func1: "(`) (f \ g) = (`) f \ (`) g" unfolding fun_eq_iff by (simp add: image_comp) lemma image_func2: "(`) id = id" by simp lemma vimage_func1: "(-`) (f \ g) = (-`) g \ (-`) f" unfolding fun_eq_iff by (simp add: vimage_comp) lemma vimage_func2: "(-`) id = id" by simp lemma iso_image: "mono ((`) f)" by (simp add: image_mono monoI) lemma iso_preimage: "mono ((-`) f)" by (simp add: monoI vimage_mono) context dual begin lemma image_dual [simp]: "(`) \ \ (`) \ = id" by (metis image_func1 image_func2 invol_dual) lemma vimage_dual [simp]: "(-`) \ \ (-`) \ = id" by (simp add: set.comp) end text \The following natural transformation between the powerset functor (image) and the identity functor is well known.\ lemma power_set_func_nat_trans: "\ \ id f = (`) f \ \" unfolding fun_eq_iff comp_def by simp text \As an instance, set-dual is a natural transformation with built-in type coercion.\ lemma dual_singleton: "(`) \ \ \ = \ \ \" by auto lemma finite_dual [simp]: "finite \ (`) \ = finite" unfolding fun_eq_iff comp_def using inj_dual finite_vimageI inj_vimage_image_eq by fastforce lemma finite_dual_var [simp]: "finite (\ ` X) = finite X" by (metis comp_def finite_dual) lemma subset_dual: "(X = \ ` Y) = (\ ` X = Y)" by (metis image_dual pointfree_idE) lemma subset_dual1: "(X \ Y) = (\ ` X \ \ ` Y)" by (simp add: inj_dual inj_image_subset_iff) lemma dual_empty [simp]: "\ ` {} = {}" by simp lemma dual_UNIV [simp]: "\ ` UNIV = UNIV" by (simp add: surj_dual) lemma fun_dual1: "(f = g \ \) = (f \ \ = g)" by (metis comp_assoc comp_id invol_dual) lemma fun_dual2: "(f = \ \ g) = (\ \ f = g)" by (metis comp_assoc fun.map_id invol_dual) lemma fun_dual3: "(f = g \ (`) \) = (f \ (`) \ = g)" by (metis comp_id image_dual o_assoc) lemma fun_dual4: "(f = (`) \ \ g) = ((`) \ \ f = g)" by (metis comp_assoc id_comp image_dual) lemma fun_dual5: "(f = \ \ g \ \) = (\ \ f \ \ = g)" by (metis comp_assoc fun_dual1 fun_dual2) lemma fun_dual6: "(f = (`) \ \ g \ (`) \) = ((`) \ \ f \ (`) \ = g)" by (simp add: comp_assoc fun_dual3 fun_dual4) lemma fun_dual7: "(f = \ \ g \ (`) \) = (\ \ f \ (`) \ = g)" by (simp add: comp_assoc fun_dual2 fun_dual3) lemma fun_dual8: "(f = (`) \ \ g \ \) = ((`) \ \ f \ \ = g)" by (simp add: comp_assoc fun_dual1 fun_dual4) lemma map_dual_dual: "(\\<^sub>F f = g) = (\\<^sub>F g = f)" by (metis map_dual_invol pointfree_idE) text \The next facts show incrementally that the dual of a complete lattice is a complete lattice.\ class ord_with_dual = dual + ord + assumes ord_dual: "x \ y \ \ y \ \ x" begin lemma dual_dual_ord: "(\ x \ \ y) = (y \ x)" by (metis dual_iff ord_dual) end lemma ord_pres_dual: fixes f :: "'a::ord_with_dual \ 'b::ord_with_dual" shows "ord_pres f \ ord_pres (\\<^sub>F f)" by (simp add: dual_dual_ord map_dual_def ord_pres_def) lemma map_dual_anti: "(f::'a::ord_with_dual \ 'b::ord_with_dual) \ g \ \\<^sub>F g \ \\<^sub>F f" by (simp add: le_fun_def map_dual_def ord_dual) class preorder_with_dual = ord_with_dual + preorder begin lemma less_dual_def_var: "(\ y < \ x) = (x < y)" by (simp add: dual_dual_ord less_le_not_le) end class order_with_dual = preorder_with_dual + order lemma iso_map_dual: fixes f :: "'a::order_with_dual \ 'b::order_with_dual" shows "mono f \ mono (\\<^sub>F f)" by (simp add: ord_pres_dual ord_pres_mono) class lattice_with_dual = lattice + dual + assumes sup_dual_def: "\ (x \ y) = \ x \ \ y" begin subclass order_with_dual by (unfold_locales, metis inf.absorb_iff2 sup_absorb1 sup_commute sup_dual_def) lemma inf_dual: "\ (x \ y) = \ x \ \ y" by (metis invol_dual_var sup_dual_def) lemma inf_to_sup: "x \ y = \ (\ x \ \ y)" using inf_dual dual_iff by fastforce lemma sup_to_inf: "x \ y = \ (\ x \ \ y)" by (simp add: inf_dual) end class bounded_lattice_with_dual = lattice_with_dual + bounded_lattice begin lemma bot_dual: "\ \ = \" by (metis dual_dual_ord dual_iff le_bot top_greatest) lemma top_dual: "\ \ = \" using bot_dual dual_iff by force end class boolean_algebra_with_dual = lattice_with_dual + boolean_algebra sublocale boolean_algebra \ badual: boolean_algebra_with_dual _ _ _ _ _ _ _ _ uminus by unfold_locales simp_all class Sup_lattice_with_dual = Sup_lattice + dual + assumes Sups_dual_def: "\ \ Sup = Infs \ (`) \" class Inf_lattice_with_dual = Inf_lattice + dual + assumes Sups_dual_def: "\ \ Supi = Inf \ (`) \" class complete_lattice_with_dual = complete_lattice + dual + assumes Sups_dual_def: "\ \ Sup = Inf \ (`) \" sublocale Sup_lattice_with_dual \ sclatd: complete_lattice_with_dual Infs Sup infs "(\)" le sups bots tops "\" by (unfold_locales, simp add: Sups_dual_def) sublocale Inf_lattice_with_dual \ iclatd: complete_lattice_with_dual Inf Supi infi "(\)" le supi boti topi "\" by (unfold_locales, simp add: Sups_dual_def) context complete_lattice_with_dual begin lemma Inf_dual: "\ \ Inf = Sup \ (`) \" by (metis comp_assoc comp_id fun.map_id Sups_dual_def image_dual invol_dual) lemma Inf_dual_var: "\ (\X) = \(\ ` X)" using comp_eq_dest Inf_dual by fastforce lemma Inf_to_Sup: "Inf = \ \ Sup \ (`) \" by (auto simp add: Sups_dual_def image_comp) lemma Inf_to_Sup_var: "\X = \ (\(\ ` X))" using Inf_dual_var dual_iff by fastforce lemma Sup_to_Inf: "Sup = \ \ Inf \ (`) \" by (auto simp add: Inf_dual image_comp) lemma Sup_to_Inf_var: "\X = \ (\(\ ` X))" using Sup_to_Inf by force lemma Sup_dual_def_var: "\ (\X) = \ (\ ` X)" using comp_eq_dest Sups_dual_def by fastforce lemma bot_dual_def: "\ \ = \" - by (smt Inf_UNIV Sup_UNIV Sups_dual_def surj_dual o_eq_dest) + by (smt (verit) Inf_UNIV Sup_UNIV Sups_dual_def surj_dual o_eq_dest) lemma top_dual_def: "\ \ = \" using bot_dual_def dual_iff by blast lemma inf_dual2: "\ (x \ y) = \ x \ \ y" - by (smt comp_eq_elim Inf_dual Inf_empty Inf_insert SUP_insert inf_top.right_neutral) + by (smt (verit) comp_eq_elim Inf_dual Inf_empty Inf_insert SUP_insert inf_top.right_neutral) lemma sup_dual: "\ (x \ y) = \ x \ \ y" by (metis inf_dual2 dual_iff) subclass lattice_with_dual by (unfold_locales, auto simp: inf_dual sup_dual) subclass bounded_lattice_with_dual.. end end diff --git a/thys/Order_Lattice_Props/Order_Lattice_Props.thy b/thys/Order_Lattice_Props/Order_Lattice_Props.thy --- a/thys/Order_Lattice_Props/Order_Lattice_Props.thy +++ b/thys/Order_Lattice_Props/Order_Lattice_Props.thy @@ -1,1227 +1,1227 @@ (* Title: Properties of Orderings and Lattices Author: Georg Struth Maintainer: Georg Struth *) section \Properties of Orderings and Lattices\ theory Order_Lattice_Props imports Order_Duality begin subsection \Basic Definitions for Orderings and Lattices\ text \The first definition is for order morphisms --- isotone (order-preserving, monotone) functions. An order isomorphism is an order-preserving bijection. This should be defined in the class ord, but mono requires order.\ definition ord_homset :: "('a::order \ 'b::order) set" where "ord_homset = {f::'a::order \ 'b::order. mono f}" definition ord_embed :: "('a::order \ 'b::order) \ bool" where "ord_embed f = (\x y. f x \ f y \ x \ y)" definition ord_iso :: "('a::order \ 'b::order) \ bool" where "ord_iso = bij \ mono \ (mono \ the_inv)" lemma ord_embed_alt: "ord_embed f = (mono f \ (\x y. f x \ f y \ x \ y))" using mono_def ord_embed_def by auto lemma ord_embed_homset: "ord_embed f \ f \ ord_homset" by (simp add: mono_def ord_embed_def ord_homset_def) lemma ord_embed_inj: "ord_embed f \ inj f" unfolding ord_embed_def inj_def by (simp add: eq_iff) lemma ord_iso_ord_embed: "ord_iso f \ ord_embed f" unfolding ord_iso_def ord_embed_def bij_def inj_def mono_def by (clarsimp, metis inj_def the_inv_f_f) lemma ord_iso_alt: "ord_iso f = (ord_embed f \ surj f)" unfolding ord_iso_def ord_embed_def surj_def bij_def inj_def mono_def apply safe by simp_all (metis eq_iff inj_def the_inv_f_f)+ lemma ord_iso_the_inv: "ord_iso f \ mono (the_inv f)" by (simp add: ord_iso_def) lemma ord_iso_inv1: "ord_iso f \ (the_inv f) \ f = id" using ord_embed_inj ord_iso_ord_embed the_inv_into_f_f by fastforce lemma ord_iso_inv2: "ord_iso f \ f \ (the_inv f) = id" using f_the_inv_into_f ord_embed_inj ord_iso_alt by fastforce typedef (overloaded) ('a,'b) ord_homset = "ord_homset::('a::order \ 'b::order) set" by (force simp: ord_homset_def mono_def) setup_lifting type_definition_ord_homset text \The next definition is for the set of fixpoints of a given function. It is important in the context of orders, for instance for proving Tarski's fixpoint theorem, but does not really belong here.\ definition Fix :: "('a \ 'a) \ 'a set" where "Fix f = {x. f x = x}" lemma retraction_prop: "f \ f = f \ f x = x \ x \ range f" by (metis comp_apply f_inv_into_f rangeI) lemma retraction_prop_fix: "f \ f = f \ range f = Fix f" unfolding Fix_def using retraction_prop by fastforce lemma Fix_map_dual: "Fix \ \\<^sub>F = (`) \ \ Fix" unfolding Fix_def map_dual_def comp_def fun_eq_iff - by (smt Collect_cong invol_dual pointfree_idE setcompr_eq_image) + by (smt (verit) Collect_cong invol_dual pointfree_idE setcompr_eq_image) lemma Fix_map_dual_var: "Fix (\\<^sub>F f) = \ ` (Fix f)" by (metis Fix_map_dual o_def) lemma gfp_dual: "(\::'a::complete_lattice_with_dual \ 'a) \ gfp = lfp \ \\<^sub>F" proof- {fix f:: "'a \ 'a" have "\ (gfp f) = \ (\{u. u \ f u})" by (simp add: gfp_def) also have "... = \(\ ` {u. u \ f u})" by (simp add: Sup_dual_def_var) also have "... = \{\ u |u. u \ f u}" by (simp add: setcompr_eq_image) also have "... = \{u |u. (\\<^sub>F f) u \ u}" by (metis (no_types, opaque_lifting) dual_dual_ord dual_iff map_dual_def o_def) finally have "\ (gfp f) = lfp (\\<^sub>F f)" by (metis lfp_def)} thus ?thesis by auto qed lemma gfp_dual_var: fixes f :: "'a::complete_lattice_with_dual \ 'a" shows "\ (gfp f) = lfp (\\<^sub>F f)" using comp_eq_elim gfp_dual by blast lemma gfp_to_lfp: "gfp = (\::'a::complete_lattice_with_dual \ 'a) \ lfp \ \\<^sub>F" by (simp add: comp_assoc fun_dual2 gfp_dual) lemma gfp_to_lfp_var: fixes f :: "'a::complete_lattice_with_dual \ 'a" shows "gfp f = \ (lfp (\\<^sub>F f))" by (metis gfp_dual_var invol_dual_var) lemma lfp_dual: "(\::'a::complete_lattice_with_dual \ 'a) \ lfp = gfp \ \\<^sub>F" by (simp add: comp_assoc gfp_to_lfp map_dual_invol) lemma lfp_dual_var: fixes f :: "'a::complete_lattice_with_dual \ 'a" shows "\ (lfp f) = gfp (map_dual f)" using comp_eq_dest_lhs lfp_dual by fastforce lemma lfp_to_gfp: "lfp = (\::'a::complete_lattice_with_dual \ 'a) \ gfp \ \\<^sub>F" by (simp add: comp_assoc gfp_dual map_dual_invol) lemma lfp_to_gfp_var: fixes f :: "'a::complete_lattice_with_dual \ 'a" shows "lfp f = \ (gfp (\\<^sub>F f))" by (metis invol_dual_var lfp_dual_var) lemma lfp_in_Fix: fixes f :: "'a::complete_lattice \ 'a" shows "mono f \ lfp f \ Fix f" by (metis (mono_tags, lifting) Fix_def lfp_unfold mem_Collect_eq) lemma gfp_in_Fix: fixes f :: "'a::complete_lattice \ 'a" shows "mono f \ gfp f \ Fix f" by (metis (mono_tags, lifting) Fix_def gfp_unfold mem_Collect_eq) lemma nonempty_Fix: fixes f :: "'a::complete_lattice \ 'a" shows "mono f \ Fix f \ {}" using lfp_in_Fix by fastforce text \Next the minimal and maximal elements of an ordering are defined.\ context ord begin definition min_set :: "'a set \ 'a set" where "min_set X = {y \ X. \x \ X. x \ y \ x = y}" definition max_set :: "'a set \ 'a set" where "max_set X = {x \ X. \y \ X. x \ y \ x = y}" end context ord_with_dual begin lemma min_max_set_dual: "(`) \ \ min_set = max_set \ (`) \" unfolding max_set_def min_set_def fun_eq_iff comp_def apply safe using dual_dual_ord inj_dual_iff by auto lemma min_max_set_dual_var: "\ ` (min_set X) = max_set (\ ` X)" using comp_eq_dest min_max_set_dual by fastforce lemma max_min_set_dual: "(`) \ \ max_set = min_set \ (`) \" by (metis (no_types, opaque_lifting) comp_id fun.map_comp id_comp image_dual min_max_set_dual) lemma min_to_max_set: "min_set = (`) \ \ max_set \ (`) \" by (metis comp_id image_dual max_min_set_dual o_assoc) lemma max_min_set_dual_var: "\ ` (max_set X) = min_set (\ ` X)" using comp_eq_dest max_min_set_dual by fastforce lemma min_to_max_set_var: "min_set X = \ ` (max_set (\ ` X))" by (simp add: max_min_set_dual_var pointfree_idE) end text \Next, directed and filtered sets, upsets, downsets, filters and ideals in posets are defined.\ context ord begin definition directed :: "'a set \ bool" where "directed X = (\Y. finite Y \ Y \ X \ (\x \ X. \y \ Y. y \ x))" definition filtered :: "'a set \ bool" where "filtered X = (\Y. finite Y \ Y \ X \ (\x \ X. \y \ Y. x \ y))" definition downset_set :: "'a set \ 'a set" ("\") where "\X = {y. \x \ X. y \ x}" definition upset_set :: "'a set \ 'a set" ("\") where "\X = {y. \x \ X. x \ y}" definition downset :: "'a \ 'a set" ("\") where "\ = \ \ \" definition upset :: "'a \ 'a set" ("\") where "\ = \ \ \" definition downsets :: "'a set set" where "downsets = Fix \" definition upsets :: "'a set set" where "upsets = Fix \" definition "downclosed_set X = (X \ downsets)" definition "upclosed_set X = (X \ upsets)" definition ideals :: "'a set set" where "ideals = {X. X \ {} \ downclosed_set X \ directed X}" definition filters :: "'a set set" where "filters = {X. X \ {} \ upclosed_set X \ filtered X}" abbreviation "idealp X \ X \ ideals" abbreviation "filterp X \ X \ filters" end text \These notions are pair-wise dual.\ text \Filtered and directed sets are dual.\ context ord_with_dual begin lemma filtered_directed_dual: "filtered \ (`) \ = directed" unfolding filtered_def directed_def fun_eq_iff comp_def apply clarsimp apply safe apply (meson finite_imageI imageI image_mono dual_dual_ord) - by (smt finite_subset_image imageE ord_dual) + by (smt (verit, ccfv_threshold) finite_subset_image imageE ord_dual) lemma directed_filtered_dual: "directed \ (`) \ = filtered" using filtered_directed_dual by (metis comp_id image_dual o_assoc) lemma filtered_to_directed: "filtered X = directed (\ ` X)" by (metis comp_apply directed_filtered_dual) text \Upsets and downsets are dual.\ lemma downset_set_upset_set_dual: "(`) \ \ \ = \ \ (`) \" unfolding downset_set_def upset_set_def fun_eq_iff comp_def apply safe apply (meson image_eqI ord_dual) by (clarsimp, metis (mono_tags, lifting) dual_iff image_iff mem_Collect_eq ord_dual) lemma upset_set_downset_set_dual: "(`) \ \ \ = \ \ (`) \" using downset_set_upset_set_dual by (metis (no_types, opaque_lifting) comp_id id_comp image_dual o_assoc) lemma upset_set_to_downset_set: "\ = (`) \ \ \ \ (`) \" by (simp add: comp_assoc downset_set_upset_set_dual) lemma upset_set_to_downset_set2: "\ X = \ ` (\ (\ ` X))" by (simp add: upset_set_to_downset_set) lemma downset_upset_dual: "(`) \ \ \ = \ \ \" using downset_def upset_def upset_set_to_downset_set by fastforce lemma upset_to_downset: "(`) \ \ \ = \ \ \" by (metis comp_assoc id_apply ord.downset_def ord.upset_def power_set_func_nat_trans upset_set_downset_set_dual) lemma upset_to_downset2: "\ = (`) \ \ \ \ \" by (simp add: comp_assoc downset_upset_dual) lemma upset_to_downset3: "\ x = \ ` (\ (\ x))" by (simp add: upset_to_downset2) lemma downsets_upsets_dual: "(X \ downsets) = (\ ` X \ upsets)" unfolding downsets_def upsets_def Fix_def - by (smt comp_eq_dest downset_set_upset_set_dual image_inv_f_f inj_dual mem_Collect_eq) + by (smt (verit) comp_eq_dest downset_set_upset_set_dual image_inv_f_f inj_dual mem_Collect_eq) lemma downset_setp_upset_setp_dual: "upclosed_set \ (`) \ = downclosed_set" unfolding downclosed_set_def upclosed_set_def using downsets_upsets_dual by fastforce lemma upsets_to_downsets: "(X \ upsets) = (\ ` X \ downsets)" by (simp add: downsets_upsets_dual image_comp) lemma upset_setp_downset_setp_dual: "downclosed_set \ (`) \ = upclosed_set" by (metis comp_id downset_setp_upset_setp_dual image_dual o_assoc) text \Filters and ideals are dual.\ lemma ideals_filters_dual: "(X \ ideals) = ((\ ` X) \ filters)" - by (smt comp_eq_dest_lhs directed_filtered_dual image_inv_f_f image_is_empty inv_unique_comp filters_def ideals_def inj_dual invol_dual mem_Collect_eq upset_setp_downset_setp_dual) + by (smt (verit) comp_eq_dest_lhs directed_filtered_dual image_inv_f_f image_is_empty inv_unique_comp filters_def ideals_def inj_dual invol_dual mem_Collect_eq upset_setp_downset_setp_dual) lemma idealp_filterp_dual: "idealp = filterp \ (`) \" unfolding fun_eq_iff by (simp add: ideals_filters_dual) lemma filters_to_ideals: "(X \ filters) = ((\ ` X) \ ideals)" by (simp add: ideals_filters_dual image_comp) lemma filterp_idealp_dual: "filterp = idealp \ (`) \" unfolding fun_eq_iff by (simp add: filters_to_ideals) end subsection \Properties of Orderings\ context ord begin lemma directed_nonempty: "directed X \ X \ {}" unfolding directed_def by fastforce lemma directed_ub: "directed X \ (\x \ X. \y \ X. \z \ X. x \ z \ y \ z)" by (meson empty_subsetI directed_def finite.emptyI finite_insert insert_subset order_refl) lemma downset_set_prop: "\ = Union \ (`) \" unfolding downset_set_def downset_def fun_eq_iff by fastforce lemma downset_set_prop_var: "\X = (\x \ X. \x)" by (simp add: downset_set_prop) lemma downset_prop: "\x = {y. y \ x}" unfolding downset_def downset_set_def fun_eq_iff by fastforce lemma downset_prop2: "y \ x \ y \ \x" by (simp add: downset_prop) lemma ideals_downsets: "X \ ideals \ X \ downsets" by (simp add: downclosed_set_def ideals_def) lemma ideals_directed: "X \ ideals \ directed X" by (simp add: ideals_def) end context preorder begin lemma directed_prop: "X \ {} \ (\x \ X. \y \ X. \z \ X. x \ z \ y \ z) \ directed X" proof- assume h1: "X \ {}" and h2: "\x \ X. \y \ X. \z \ X. x \ z \ y \ z" {fix Y have "finite Y \ Y \ X \ (\x \ X. \y \ Y. y \ x)" proof (induct rule: finite_induct) case empty then show ?case using h1 by blast next case (insert x F) then show ?case by (metis h2 insert_iff insert_subset order_trans) qed} thus ?thesis by (simp add: directed_def) qed lemma directed_alt: "directed X = (X \ {} \ (\x \ X. \y \ X. \z \ X. x \ z \ y \ z))" by (metis directed_prop directed_nonempty directed_ub) lemma downset_set_prop_var2: "x \ \X \ y \ x \ y \ \X" unfolding downset_set_def using order_trans by blast lemma downclosed_set_iff: "downclosed_set X = (\x \ X. \y. y \ x \ y \ X)" unfolding downclosed_set_def downsets_def Fix_def downset_set_def by auto lemma downclosed_downset_set: "downclosed_set (\X)" by (simp add: downclosed_set_iff downset_set_prop_var2 downset_def) lemma downclosed_downset: "downclosed_set (\x)" by (simp add: downclosed_downset_set downset_def) lemma downset_set_ext: "id \ \" unfolding le_fun_def id_def downset_set_def by auto lemma downset_set_iso: "mono \" unfolding mono_def downset_set_def by blast lemma downset_set_idem [simp]: "\ \ \ = \" unfolding fun_eq_iff downset_set_def using order_trans by auto lemma downset_faithful: "\x \ \y \ x \ y" by (simp add: downset_prop subset_eq) lemma downset_iso_iff: "(\x \ \y) = (x \ y)" using atMost_iff downset_prop order_trans by blast text \The following proof uses the Axiom of Choice.\ lemma downset_directed_downset_var [simp]: "directed (\X) = directed X" proof assume h1: "directed X" {fix Y assume h2: "finite Y" and h3: "Y \ \X" hence "\y. \x. y \ Y \ x \ X \ y \ x" by (force simp: downset_set_def) hence "\f. \y. y \ Y \ f y \ X \ y \ f y" by (rule choice) hence "\f. finite (f ` Y) \ f ` Y \ X \ (\y \ Y. y \ f y)" by (metis finite_imageI h2 image_subsetI) hence "\Z. finite Z \ Z \ X \ (\y \ Y. \ z \ Z. y \ z)" by fastforce hence "\Z. finite Z \ Z \ X \ (\y \ Y. \ z \ Z. y \ z) \ (\x \ X. \ z \ Z. z \ x)" by (metis directed_def h1) hence "\x \ X. \y \ Y. y \ x" by (meson order_trans)} thus "directed (\X)" unfolding directed_def downset_set_def by fastforce next assume "directed (\X)" thus "directed X" unfolding directed_def downset_set_def apply clarsimp - by (smt Ball_Collect order_refl order_trans subsetCE) + by (smt (verit) Ball_Collect order_refl order_trans subsetCE) qed lemma downset_directed_downset [simp]: "directed \ \ = directed" unfolding fun_eq_iff by simp lemma directed_downset_ideals: "directed (\X) = (\X \ ideals)" by (metis (mono_tags, lifting) CollectI Fix_def directed_alt downset_set_idem downclosed_set_def downsets_def ideals_def o_def ord.ideals_directed) lemma downclosed_Fix: "downclosed_set X = (\X = X)" by (metis (mono_tags, lifting) CollectD Fix_def downclosed_downset_set downclosed_set_def downsets_def) end lemma downset_iso: "mono (\::'a::order \ 'a set)" by (simp add: downset_iso_iff mono_def) lemma mono_downclosed: fixes f :: "'a::order \ 'b::order" assumes "mono f" shows "\Y. downclosed_set Y \ downclosed_set (f -` Y)" by (simp add: assms downclosed_set_iff monoD) lemma fixes f :: "'a::order \ 'b::order" assumes "mono f" shows "\Y. downclosed_set X \ downclosed_set (f ` X)" (*nitpick*) oops lemma downclosed_mono: fixes f :: "'a::order \ 'b::order" assumes "\Y. downclosed_set Y \ downclosed_set (f -` Y)" shows "mono f" proof- {fix x y :: "'a::order" assume h: "x \ y" have "downclosed_set (\ (f y))" unfolding downclosed_set_def downsets_def Fix_def downset_set_def downset_def by auto hence "downclosed_set (f -` (\ (f y)))" by (simp add: assms) hence "downclosed_set {z. f z \ f y}" unfolding vimage_def downset_def downset_set_def by auto hence "\z w. (f z \ f y \ w \ z) \ f w \ f y" unfolding downclosed_set_def downclosed_set_def downsets_def Fix_def downset_set_def by force hence "f x \ f y" using h by blast} thus ?thesis.. qed lemma mono_downclosed_iff: "mono f = (\Y. downclosed_set Y \ downclosed_set (f -` Y))" using mono_downclosed downclosed_mono by auto context order begin lemma downset_inj: "inj \" by (metis injI downset_iso_iff order.eq_iff) lemma "(X \ Y) = (\X \ \Y)" (*nitpick*) oops end context lattice begin lemma lat_ideals: "X \ ideals = (X \ {} \ X \ downsets \ (\x \ X. \ y \ X. x \ y \ X))" unfolding ideals_def directed_alt downsets_def Fix_def downset_set_def downclosed_set_def - by (clarsimp, smt sup.cobounded1 sup.orderE sup.orderI sup_absorb2 sup_left_commute mem_Collect_eq) + using local.sup.bounded_iff local.sup_ge2 by blast + end context bounded_lattice begin lemma bot_ideal: "X \ ideals \ \ \ X" unfolding ideals_def downclosed_set_def downsets_def Fix_def downset_set_def by fastforce end context complete_lattice begin lemma Sup_downset_id [simp]: "Sup \ \ = id" using Sup_atMost atMost_def downset_prop by fastforce lemma downset_Sup_id: "id \ \ \ Sup" by (simp add: Sup_upper downset_prop le_funI subsetI) lemma Inf_Sup_var: "\(\x \ X. \x) = \X" unfolding downset_prop by (simp add: Collect_ball_eq Inf_eq_Sup) lemma Inf_pres_downset_var: "(\x \ X. \x) = \(\X)" unfolding downset_prop by (safe, simp_all add: le_Inf_iff) end subsection \Dual Properties of Orderings\ context ord_with_dual begin lemma filtered_nonempty: "filtered X \ X \ {}" using filtered_to_directed ord.directed_nonempty by auto lemma filtered_lb: "filtered X \ (\x \ X. \y \ X. \z \ X. z \ x \ z \ y)" using filtered_to_directed directed_ub dual_dual_ord by fastforce lemma upset_set_prop_var: "\X = (\x \ X. \x)" by (simp add: image_Union downset_set_prop_var upset_set_to_downset_set2 upset_to_downset2) lemma upset_set_prop: "\ = Union \ (`) \" unfolding fun_eq_iff by (simp add: upset_set_prop_var) lemma upset_prop: "\x = {y. x \ y}" unfolding upset_to_downset3 downset_prop image_def using dual_dual_ord by fastforce lemma upset_prop2: "x \ y \ y \ \x" by (simp add: upset_prop) lemma filters_upsets: "X \ filters \ X \ upsets" by (simp add: upclosed_set_def filters_def) lemma filters_filtered: "X \ filters \ filtered X" by (simp add: filters_def) end context preorder_with_dual begin lemma filtered_prop: "X \ {} \ (\x \ X. \y \ X. \z \ X. z \ x \ z \ y) \ filtered X" unfolding filtered_to_directed by (rule directed_prop, blast, metis (full_types) image_iff ord_dual) lemma filtered_alt: "filtered X = (X \ {} \ (\x \ X. \y \ X. \z \ X. z \ x \ z \ y))" by (metis image_empty directed_alt filtered_to_directed filtered_lb filtered_prop) lemma up_set_prop_var2: "x \ \X \ x \ y \ y \ \X" using downset_set_prop_var2 dual_iff ord_dual upset_set_to_downset_set2 by fastforce lemma upclosed_set_iff: "upclosed_set X = (\x \ X. \y. x \ y \ y \ X)" unfolding upclosed_set_def upsets_def Fix_def upset_set_def by auto lemma upclosed_upset_set: "upclosed_set (\X)" using up_set_prop_var2 upclosed_set_iff by blast lemma upclosed_upset: "upclosed_set (\x)" by (simp add: upset_def upclosed_upset_set) lemma upset_set_ext: "id \ \" - by (smt comp_def comp_id image_mono le_fun_def downset_set_ext image_dual upset_set_to_downset_set2) + by (smt (verit) comp_def comp_id image_mono le_fun_def downset_set_ext image_dual upset_set_to_downset_set2) lemma upset_set_anti: "mono \" by (metis image_mono downset_set_iso upset_set_to_downset_set2 mono_def) lemma up_set_idem [simp]: "\ \ \ = \" by (metis comp_assoc downset_set_idem upset_set_downset_set_dual upset_set_to_downset_set) lemma upset_faithful: "\x \ \y \ y \ x" by (metis inj_image_subset_iff downset_faithful dual_dual_ord inj_dual upset_to_downset3) lemma upset_anti_iff: "(\y \ \x) = (x \ y)" by (metis downset_iso_iff ord_dual upset_to_downset3 subset_image_iff upset_faithful) lemma upset_filtered_upset [simp]: "filtered \ \ = filtered" by (metis comp_assoc directed_filtered_dual downset_directed_downset upset_set_downset_set_dual) lemma filtered_upset_filters: "filtered (\X) = (\X \ filters)" by (metis comp_apply directed_downset_ideals filtered_to_directed filterp_idealp_dual upset_set_downset_set_dual) lemma upclosed_Fix: "upclosed_set X = (\X = X)" by (simp add: Fix_def upclosed_set_def upsets_def) end lemma upset_anti: "antimono (\::'a::order_with_dual \ 'a set)" by (simp add: antimono_def upset_anti_iff) lemma mono_upclosed: fixes f :: "'a::order_with_dual \ 'b::order_with_dual" assumes "mono f" shows "\Y. upclosed_set Y \ upclosed_set (f -` Y)" by (simp add: assms monoD upclosed_set_iff) lemma mono_upclosed: fixes f :: "'a::order_with_dual \ 'b::order_with_dual" assumes "mono f" shows "\Y. upclosed_set X \ upclosed_set (f ` X)" (*nitpick*) oops lemma upclosed_mono: fixes f :: "'a::order_with_dual \ 'b::order_with_dual" assumes "\Y. upclosed_set Y \ upclosed_set (f -` Y)" shows "mono f" by (metis (mono_tags, lifting) assms dual_order.refl mem_Collect_eq monoI order.trans upclosed_set_iff vimageE vimageI2) lemma mono_upclosed_iff: fixes f :: "'a::order_with_dual \ 'b::order_with_dual" shows "mono f = (\Y. upclosed_set Y \ upclosed_set (f -` Y))" using mono_upclosed upclosed_mono by auto context order_with_dual begin lemma upset_inj: "inj \" by (metis inj_compose inj_on_imageI2 downset_inj inj_dual upset_to_downset) lemma "(X \ Y) = (\Y \ \X)" (*nitpick*) oops end context lattice_with_dual begin lemma lat_filters: "X \ filters = (X \ {} \ X \ upsets \ (\x \ X. \ y \ X. x \ y \ X))" unfolding filters_to_ideals upsets_to_downsets inf_to_sup lat_ideals - by (smt image_iff image_inv_f_f image_is_empty inj_image_mem_iff inv_unique_comp inj_dual invol_dual) + by (smt (verit) image_iff image_inv_f_f image_is_empty inj_image_mem_iff inv_unique_comp inj_dual invol_dual) end context bounded_lattice_with_dual begin lemma top_filter: "X \ filters \ \ \ X" using bot_ideal inj_image_mem_iff inj_dual filters_to_ideals top_dual by fastforce end context complete_lattice_with_dual begin lemma Inf_upset_id [simp]: "Inf \ \ = id" by (metis comp_assoc comp_id Sup_downset_id Sups_dual_def downset_upset_dual invol_dual) lemma upset_Inf_id: "id \ \ \ Inf" by (simp add: Inf_lower le_funI subsetI upset_prop) lemma Sup_Inf_var: " \(\x \ X. \x) = \X" unfolding upset_prop by (simp add: Collect_ball_eq Sup_eq_Inf) lemma Sup_dual_upset_var: "(\x \ X. \x) = \(\X)" unfolding upset_prop by (safe, simp_all add: Sup_le_iff) end subsection \Properties of Complete Lattices\ definition "Inf_closed_set X = (\Y \ X. \Y \ X)" definition "Sup_closed_set X = (\Y \ X. \Y \ X)" definition "inf_closed_set X = (\x \ X. \y \ X. x \ y \ X)" definition "sup_closed_set X = (\x \ X. \y \ X. x \ y \ X)" text \The following facts about complete lattices add to those in the Isabelle libraries.\ context complete_lattice begin text \The translation between sup and Sup could be improved. The sup-theorems should be direct consequences of Sup-ones. In addition, duality between sup and inf is currently not exploited.\ lemma sup_Sup: "x \ y = \{x,y}" by simp lemma inf_Inf: "x \ y = \{x,y}" by simp text \The next two lemmas are about Sups and Infs of indexed families. These are interesting for iterations and fixpoints.\ lemma fSup_unfold: "(f::nat \ 'a) 0 \ (\n. f (Suc n)) = (\n. f n)" apply (intro order.antisym sup_least) apply (rule Sup_upper, force) apply (rule Sup_mono, force) apply (safe intro!: Sup_least) by (case_tac n, simp_all add: Sup_upper le_supI2) lemma fInf_unfold: "(f::nat \ 'a) 0 \ (\n. f (Suc n)) = (\n. f n)" apply (intro order.antisym inf_greatest) apply (rule Inf_greatest, safe) apply (case_tac n) apply simp_all using Inf_lower inf.coboundedI2 apply force apply (simp add: Inf_lower) by (auto intro: Inf_mono) end lemma Sup_sup_closed: "Sup_closed_set (X::'a::complete_lattice set) \ sup_closed_set X" by (metis Sup_closed_set_def empty_subsetI insert_subsetI sup_Sup sup_closed_set_def) lemma Inf_inf_closed: "Inf_closed_set (X::'a::complete_lattice set) \ inf_closed_set X" by (metis Inf_closed_set_def empty_subsetI inf_Inf inf_closed_set_def insert_subset) subsection \Sup- and Inf-Preservation\ text \Next, important notation for morphism between posets and lattices is introduced: sup-preservation, inf-preservation and related properties.\ abbreviation Sup_pres :: "('a::Sup \ 'b::Sup) \ bool" where "Sup_pres f \ f \ Sup = Sup \ (`) f" abbreviation Inf_pres :: "('a::Inf \ 'b::Inf) \ bool" where "Inf_pres f \ f \ Inf = Inf \ (`) f" abbreviation sup_pres :: "('a::sup \ 'b::sup) \ bool" where "sup_pres f \ (\x y. f (x \ y) = f x \ f y)" abbreviation inf_pres :: "('a::inf \ 'b::inf) \ bool" where "inf_pres f \ (\x y. f (x \ y) = f x \ f y)" abbreviation bot_pres :: "('a::bot \ 'b::bot) \ bool" where "bot_pres f \ f \ = \" abbreviation top_pres :: "('a::top \ 'b::top) \ bool" where "top_pres f \ f \ = \" abbreviation Sup_dual :: "('a::Sup \ 'b::Inf) \ bool" where "Sup_dual f \ f \ Sup = Inf \ (`) f" abbreviation Inf_dual :: "('a::Inf \ 'b::Sup) \ bool" where "Inf_dual f \ f \ Inf = Sup \ (`) f" abbreviation sup_dual :: "('a::sup \ 'b::inf) \ bool" where "sup_dual f \ (\x y. f (x \ y) = f x \ f y)" abbreviation inf_dual :: "('a::inf \ 'b::sup) \ bool" where "inf_dual f \ (\x y. f (x \ y) = f x \ f y)" abbreviation bot_dual :: "('a::bot \ 'b::top) \ bool" where "bot_dual f \ f \ = \" abbreviation top_dual :: "('a::top \ 'b::bot) \ bool" where "top_dual f \ f \ = \" text \Inf-preservation and sup-preservation relate with duality.\ lemma Inf_pres_map_dual_var: "Inf_pres f = Sup_pres (\\<^sub>F f)" for f :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" proof - { fix x :: "'a set" assume "\ (f (\ (\ ` x))) = (\y\x. \ (f (\ y)))" for x then have "\ (f ` \ ` A) = f (\ (\ A))" for A by (metis (no_types) Sup_dual_def_var image_image invol_dual_var subset_dual) then have "\ (f ` x) = f (\ x)" by (metis Sup_dual_def_var subset_dual) } then show ?thesis by (auto simp add: map_dual_def fun_eq_iff Inf_dual_var Sup_dual_def_var image_comp) qed lemma Inf_pres_map_dual: "Inf_pres = Sup_pres \ (\\<^sub>F::('a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual) \ 'a \ 'b)" proof- {fix f::"'a \ 'b" have "Inf_pres f = (Sup_pres \ \\<^sub>F) f" by (simp add: Inf_pres_map_dual_var)} thus ?thesis by force qed lemma Sup_pres_map_dual_var: fixes f :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" shows "Sup_pres f = Inf_pres (\\<^sub>F f)" by (metis Inf_pres_map_dual_var fun_dual5 map_dual_def) lemma Sup_pres_map_dual: "Sup_pres = Inf_pres \ (\\<^sub>F::('a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual) \ 'a \ 'b)" by (simp add: Inf_pres_map_dual comp_assoc map_dual_invol) text \The following lemmas relate isotonicity of functions between complete lattices with weak (left) preservation properties of sups and infs.\ lemma fun_isol: "mono f \ mono ((\) f)" by (simp add: le_fun_def mono_def) lemma fun_isor: "mono f \ mono (\x. x \ f)" by (simp add: le_fun_def mono_def) lemma Sup_sup_pres: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "Sup_pres f \ sup_pres f" by (metis (no_types, opaque_lifting) Sup_empty Sup_insert comp_apply image_insert sup_bot.right_neutral) lemma Inf_inf_pres: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows"Inf_pres f \ inf_pres f" - by (smt INF_insert Inf_empty Inf_insert comp_eq_elim inf_top.right_neutral) + by (smt (verit) INF_insert Inf_empty Inf_insert comp_eq_elim inf_top.right_neutral) lemma Sup_bot_pres: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "Sup_pres f \ bot_pres f" by (metis SUP_empty Sup_empty comp_eq_elim) lemma Inf_top_pres: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "Inf_pres f \ top_pres f" by (metis INF_empty Inf_empty comp_eq_elim) lemma Sup_sup_dual: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "Sup_dual f \ sup_dual f" - by (smt comp_eq_elim image_empty image_insert inf_Inf sup_Sup) + by (smt (verit) comp_eq_elim image_empty image_insert inf_Inf sup_Sup) lemma Inf_inf_dual: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "Inf_dual f \ inf_dual f" - by (smt comp_eq_elim image_empty image_insert inf_Inf sup_Sup) + by (smt (verit) comp_eq_elim image_empty image_insert inf_Inf sup_Sup) lemma Sup_bot_dual: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "Sup_dual f \ bot_dual f" by (metis INF_empty Sup_empty comp_eq_elim) lemma Inf_top_dual: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "Inf_dual f \ top_dual f" by (metis Inf_empty SUP_empty comp_eq_elim) text \However, Inf-preservation does not imply top-preservation and Sup-preservation does not imply bottom-preservation.\ lemma fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "Sup_pres f \ top_pres f" (*nitpick*) oops lemma fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "Inf_pres f \ bot_pres f" (*nitpick*) oops context complete_lattice begin lemma iso_Inf_subdistl: fixes f :: "'a \ 'b::complete_lattice" shows "mono f \f \ Inf \ Inf \ (`) f" by (simp add: complete_lattice_class.le_Inf_iff le_funI Inf_lower monoD) lemma iso_Sup_supdistl: fixes f :: "'a \ 'b::complete_lattice" shows "mono f \ Sup \ (`) f \ f \ Sup" by (simp add: complete_lattice_class.Sup_le_iff le_funI Sup_upper monoD) lemma Inf_subdistl_iso: fixes f :: "'a \ 'b::complete_lattice" shows "f \ Inf \ Inf \ (`) f \ mono f" unfolding mono_def le_fun_def comp_def by (metis complete_lattice_class.le_INF_iff Inf_atLeast atLeast_iff) lemma Sup_supdistl_iso: fixes f :: "'a \ 'b::complete_lattice" shows "Sup \ (`) f \ f \ Sup \ mono f" unfolding mono_def le_fun_def comp_def by (metis complete_lattice_class.SUP_le_iff Sup_atMost atMost_iff) lemma supdistl_iso: fixes f :: "'a \ 'b::complete_lattice" shows "(Sup \ (`) f \ f \ Sup) = mono f" using Sup_supdistl_iso iso_Sup_supdistl by force lemma subdistl_iso: fixes f :: "'a \ 'b::complete_lattice" shows "(f \ Inf \ Inf \ (`) f) = mono f" using Inf_subdistl_iso iso_Inf_subdistl by force end lemma ord_iso_Inf_pres: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "ord_iso f \ Inf \ (`) f = f \ Inf" proof- let ?g = "the_inv f" assume h: "ord_iso f" hence a: "mono ?g" by (simp add: ord_iso_the_inv) {fix X :: "'a::complete_lattice set" {fix y :: "'b::complete_lattice" have "(y \ f (\X)) = (?g y \ \X)" by (metis (mono_tags, lifting) UNIV_I f_the_inv_into_f h monoD ord_embed_alt ord_embed_inj ord_iso_alt) also have "... = (\x \ X. ?g y \ x)" by (simp add: le_Inf_iff) also have "... = (\x \ X. y \ f x)" by (metis (mono_tags, lifting) UNIV_I f_the_inv_into_f h monoD ord_embed_alt ord_embed_inj ord_iso_alt) also have "... = (y \ \ (f ` X))" by (simp add: le_INF_iff) finally have "(y \ f (\X)) = (y \ \ (f ` X))".} hence "f (\X) = \ (f ` X)" by (meson dual_order.antisym order_refl)} thus ?thesis unfolding fun_eq_iff by simp qed lemma ord_iso_Sup_pres: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "ord_iso f \ Sup \ (`) f = f \ Sup" proof- let ?g = "the_inv f" assume h: "ord_iso f" hence a: "mono ?g" by (simp add: ord_iso_the_inv) {fix X :: "'a::complete_lattice set" {fix y :: "'b::complete_lattice" have "(f (\X) \ y) = (\X \ ?g y)" by (metis (mono_tags, lifting) UNIV_I f_the_inv_into_f h monoD ord_embed_alt ord_embed_inj ord_iso_alt) also have "... = (\x \ X. x \ ?g y)" by (simp add: Sup_le_iff) also have "... = (\x \ X. f x \ y)" by (metis (mono_tags, lifting) UNIV_I f_the_inv_into_f h monoD ord_embed_alt ord_embed_inj ord_iso_alt) also have "... = (\ (f ` X) \ y)" by (simp add: SUP_le_iff) finally have "(f (\X) \ y) = (\ (f ` X) \ y)".} hence "f (\X) = \ (f ` X)" by (meson dual_order.antisym order_refl)} thus ?thesis unfolding fun_eq_iff by simp qed text \Right preservation of sups and infs is trivial.\ lemma fSup_distr: "Sup_pres (\x. x \ f)" unfolding fun_eq_iff by (simp add: image_comp) lemma fSup_distr_var: "\F \ g = (\f \ F. f \ g)" unfolding fun_eq_iff by (simp add: image_comp) lemma fInf_distr: "Inf_pres (\x. x \ f)" unfolding fun_eq_iff comp_def - by (smt INF_apply Inf_fun_def Sup.SUP_cong) + by (smt (verit) INF_apply Inf_fun_def Sup.SUP_cong) lemma fInf_distr_var: "\F \ g = (\f \ F. f \ g)" unfolding fun_eq_iff comp_def - by (smt INF_apply INF_cong INF_image Inf_apply image_comp image_def image_image) + by (smt (verit) INF_apply INF_cong INF_image Inf_apply image_comp image_def image_image) text \The next set of lemma revisits the preservation properties in the function space.\ lemma fSup_subdistl: assumes "mono (f::'a::complete_lattice \ 'b::complete_lattice)" shows "Sup \ (`) ((\) f) \ (\) f \ Sup" using assms by (simp add: fun_isol supdistl_iso) lemma fSup_subdistl_var: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "mono f \ (\g \ G. f \ g) \ f \ \G" by (simp add: fun_isol mono_Sup) lemma fInf_subdistl: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "mono f \ (\) f \ Inf \ Inf \ (`) ((\) f)" by (simp add: fun_isol subdistl_iso) lemma fInf_subdistl_var: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "mono f \ f \ \G \ (\g \ G. f \ g)" by (simp add: fun_isol mono_Inf) lemma fSup_distl: "Sup_pres f \ Sup_pres ((\) f)" unfolding fun_eq_iff by (simp add: image_comp) lemma fSup_distl_var: "Sup_pres f \ f \ \G = (\g \ G. f \ g)" unfolding fun_eq_iff by (simp add: image_comp) lemma fInf_distl: "Inf_pres f \ Inf_pres ((\) f)" unfolding fun_eq_iff by (simp add: image_comp) lemma fInf_distl_var: "Inf_pres f \ f \ \G = (\g \ G. f \ g)" unfolding fun_eq_iff by (simp add: image_comp) text \Downsets preserve infs whereas upsets preserve sups.\ lemma Inf_pres_downset: "Inf_pres (\::'a::complete_lattice_with_dual \ 'a set)" unfolding downset_prop fun_eq_iff by (safe, simp_all add: le_Inf_iff) lemma Sup_dual_upset: "Sup_dual (\::'a::complete_lattice_with_dual \ 'a set)" unfolding upset_prop fun_eq_iff by (safe, simp_all add: Sup_le_iff) text \Images of Sup-morphisms are closed under Sups and images of Inf-morphisms are closed under Infs.\ lemma Sup_pres_Sup_closed: "Sup_pres f \ Sup_closed_set (range f)" by (metis (mono_tags, lifting) Sup_closed_set_def comp_eq_elim range_eqI subset_image_iff) lemma Inf_pres_Inf_closed: "Inf_pres f \ Inf_closed_set (range f)" by (metis (mono_tags, lifting) Inf_closed_set_def comp_eq_elim range_eqI subset_image_iff) text \It is well known that functions into complete lattices form complete lattices. Here, such results are shown for the subclasses of isotone functions, where additional closure conditions must be respected.\ typedef (overloaded) 'a iso = "{f::'a::order \ 'a::order. mono f}" by (metis Abs_ord_homset_cases ord_homset_def) setup_lifting type_definition_iso instantiation iso :: (complete_lattice) complete_lattice begin lift_definition Inf_iso :: "'a::complete_lattice iso set \ 'a iso" is Sup by (metis (mono_tags, lifting) SUP_subset_mono Sup_apply mono_def subsetI) lift_definition Sup_iso :: "'a::complete_lattice iso set \ 'a iso" is Inf - by (smt INF_lower2 Inf_apply le_INF_iff mono_def) + by (smt (verit) INF_lower2 Inf_apply le_INF_iff mono_def) lift_definition bot_iso :: "'a::complete_lattice iso" is "\" by (simp add: monoI) lift_definition sup_iso :: "'a::complete_lattice iso \ 'a iso \ 'a iso" is inf - by (smt inf_apply inf_mono monoD monoI) + by (smt (verit) inf_apply inf_mono monoD monoI) lift_definition top_iso :: "'a::complete_lattice iso" is "\" by (simp add: mono_def) lift_definition inf_iso :: "'a::complete_lattice iso \ 'a iso \ 'a iso" is sup - by (smt mono_def sup.mono sup_apply) + by (smt (verit) mono_def sup.mono sup_apply) lift_definition less_eq_iso :: "'a::complete_lattice iso \ 'a iso \ bool" is "(\)". lift_definition less_iso :: "'a::complete_lattice iso \ 'a iso \ bool" is "(>)". instance by (intro_classes; transfer, simp_all add: less_fun_def Sup_upper Sup_least Inf_lower Inf_greatest) end text \Duality has been baked into this result because of its relevance for predicate transformers. A proof where Sups are mapped to Sups and Infs to Infs is certainly possible, but two instantiation of the same type and the same classes are unfortunately impossible. Interpretations could be used instead. A corresponding result for Inf-preseving functions and Sup-lattices, is proved in components on transformers, as more advanced properties about Inf-preserving functions are needed.\ subsection \Alternative Definitions for Complete Boolean Algebras\ text \The current definitions of complete boolean algebras deviates from that in most textbooks in that a distributive law with infinite sups and infinite infs is used. There are interesting applications, for instance in topology, where weaker laws are needed --- for instance for frames and locales.\ class complete_heyting_algebra = complete_lattice + assumes ch_dist: "x \ \Y = (\y \ Y. x \ y)" text \Complete Heyting algebras are also known as frames or locales (they differ with respect to their morphisms).\ class complete_co_heyting_algebra = complete_lattice + assumes co_ch_dist: "x \ \Y = (\y \ Y. x \ y)" class complete_boolean_algebra_alt = complete_lattice + boolean_algebra instance set :: (type) complete_boolean_algebra_alt.. context complete_boolean_algebra_alt begin subclass complete_heyting_algebra proof fix x Y {fix t have "(x \ \Y \ t) = (\Y \ -x \ t)" by (simp add: inf.commute shunt1[symmetric]) also have "... = (\y \ Y. y \ -x \ t)" using Sup_le_iff by blast also have "... = (\y \ Y. x \ y \ t)" by (simp add: inf.commute shunt1) finally have "(x \ \Y \ t) = ((\y\Y. x \ y) \ t)" by (simp add: local.SUP_le_iff)} thus "x \ \Y = (\y\Y. x \ y)" using order.eq_iff by blast qed subclass complete_co_heyting_algebra apply unfold_locales apply (rule order.antisym) apply (simp add: INF_greatest Inf_lower2) by (meson eq_refl le_INF_iff le_Inf_iff shunt2) lemma de_morgan1: "-(\X) = (\x \ X. -x)" proof- {fix y have "(y \ -(\X)) = (\X \ -y)" using compl_le_swap1 by blast also have "... = (\x \ X. x \ -y)" by (simp add: Sup_le_iff) also have "... = (\x \ X. y \ -x)" using compl_le_swap1 by blast also have "... = (y \ (\x \ X. -x))" using le_INF_iff by force finally have "(y \ -(\X)) = (y \(\x \ X. -x))".} thus ?thesis using order.antisym by blast qed lemma de_morgan2: "-(\X) = (\x \ X. -x)" by (metis de_morgan1 ba_dual.dual_iff ba_dual.image_dual pointfree_idE) end class complete_boolean_algebra_alt_with_dual = complete_lattice_with_dual + complete_boolean_algebra_alt instantiation set :: (type) complete_boolean_algebra_alt_with_dual begin definition dual_set :: "'a set \ 'a set" where "dual_set = uminus" instance by intro_classes (simp_all add: ba_dual.inj_dual dual_set_def comp_def uminus_Sup id_def) end context complete_boolean_algebra_alt begin sublocale cba_dual: complete_boolean_algebra_alt_with_dual _ _ _ _ _ _ _ _ uminus _ _ by unfold_locales (auto simp: de_morgan2 de_morgan1) end subsection \Atomic Boolean Algebras\ text \Next, atomic boolean algebras are defined.\ context bounded_lattice begin text \Atoms are covers of bottom.\ definition "atom x = (x \ \ \ \(\y. \ < y \ y < x))" definition "atom_map x = {y. atom y \ y \ x}" lemma atom_map_def_var: "atom_map x = \x \ Collect atom" unfolding atom_map_def downset_def downset_set_def comp_def atom_def by fastforce lemma atom_map_atoms: "\(range atom_map) = Collect atom" unfolding atom_map_def atom_def by auto end typedef (overloaded) 'a atoms = "range (atom_map::'a::bounded_lattice \ 'a set)" by blast setup_lifting type_definition_atoms definition at_map :: "'a::bounded_lattice \ 'a atoms" where "at_map = Abs_atoms \ atom_map" class atomic_boolean_algebra = boolean_algebra + assumes atomicity: "x \ \ \ (\y. atom y \ y \ x)" class complete_atomic_boolean_algebra = complete_lattice + atomic_boolean_algebra begin subclass complete_boolean_algebra_alt.. end text \Here are two equivalent definitions for atoms; first in boolean algebras, and then in complete boolean algebras.\ context boolean_algebra begin text \The following two conditions are taken from Koppelberg's book~\<^cite>\"Koppelberg89"\.\ lemma atom_neg: "atom x \ x \ \ \ (\y z. x \ y \ x \ -y)" by (auto simp add: atom_def) (metis local.dual_order.not_eq_order_implies_strict local.inf.cobounded1 local.inf.cobounded2 local.inf_shunt) lemma atom_sup: "(\y. x \ y \ x \ -y) \ (\y z. (x \ y \ x \ z) = (x \ y \ z))" by (metis inf.orderE le_supI1 shunt2) lemma sup_atom: "x \ \ \ (\y z. (x \ y \ x \ z) = (x \ y \ z)) \ atom x" by (auto simp add: atom_def) (metis (full_types) local.inf.boundedI local.inf.cobounded2 local.inf_shunt local.inf_sup_ord(4) local.le_iff_sup local.shunt1 local.sup.absorb1 local.sup.strict_order_iff) lemma atom_sup_iff: "atom x = (x \ \ \ (\y z. (x \ y \ x \ z) = (x \ y \ z)))" by rule (auto simp add: atom_neg atom_sup sup_atom) lemma atom_neg_iff: "atom x = (x \ \ \ (\y z. x \ y \ x \ -y))" by rule (auto simp add: atom_neg atom_sup sup_atom) lemma atom_map_bot_pres: "atom_map \ = {}" using atom_def atom_map_def le_bot by auto lemma atom_map_top_pres: "atom_map \ = Collect atom" using atom_map_def by auto end context complete_boolean_algebra_alt begin lemma atom_Sup: "\Y. x \ \ \ (\y. x \ y \ x \ -y) \ ((\y \ Y. x \ y) = (x \ \Y))" by (metis Sup_least Sup_upper2 compl_le_swap1 le_iff_inf inf_shunt) lemma Sup_atom: "x \ \ \ (\Y. (\y \ Y. x \ y) = (x \ \Y)) \ atom x" proof- assume h1: "x \ \" and h2: "\Y. (\y \ Y. x \ y) = (x \ \Y)" hence "\y z. (x \ y \ x \ z) = (x \ y \ z)" - - by (smt insert_iff sup_Sup sup_bot.right_neutral) + by (smt (verit) insert_iff sup_Sup sup_bot.right_neutral) thus "atom x" by (simp add: h1 sup_atom) qed lemma atom_Sup_iff: "atom x = (x \ \ \ (\Y. (\y \ Y. x \ y) = (x \ \Y)))" by standard (auto simp: atom_neg atom_Sup Sup_atom) end end diff --git a/thys/Order_Lattice_Props/Order_Lattice_Props_Loc.thy b/thys/Order_Lattice_Props/Order_Lattice_Props_Loc.thy --- a/thys/Order_Lattice_Props/Order_Lattice_Props_Loc.thy +++ b/thys/Order_Lattice_Props/Order_Lattice_Props_Loc.thy @@ -1,575 +1,575 @@ (* Title: Locale-Based Duality Author: Georg Struth Maintainer:Georg Struth *) section \Locale-Based Duality\ theory Order_Lattice_Props_Loc imports Main begin unbundle lattice_syntax text \This section explores order and lattice duality based on locales. Used within the context of a class or locale, this is very effective, though more opaque than the previous approach. Outside of such a context, however, it apparently cannot be used for dualising theorems. Examples are properties of functions between orderings or lattices.\ definition Fix :: "('a \ 'a) \ 'a set" where "Fix f = {x. f x = x}" context ord begin definition min_set :: "'a set \ 'a set" where "min_set X = {y \ X. \x \ X. x \ y \ x = y}" definition max_set :: "'a set \ 'a set" where "max_set X = {x \ X. \y \ X. x \ y \ x = y}" definition directed :: "'a set \ bool" where "directed X = (\Y. finite Y \ Y \ X \ (\x \ X. \y \ Y. y \ x))" definition filtered :: "'a set \ bool" where "filtered X = (\Y. finite Y \ Y \ X \ (\x \ X. \y \ Y. x \ y))" definition downset_set :: "'a set \ 'a set" ("\") where "\X = {y. \x \ X. y \ x}" definition upset_set :: "'a set \ 'a set" ("\") where "\X = {y. \x \ X. x \ y}" definition downset :: "'a \ 'a set" ("\") where "\ = \ \ (\x. {x})" definition upset :: "'a \ 'a set" ("\") where "\ = \ \ (\x. {x})" definition downsets :: "'a set set" where "downsets = Fix \" definition upsets :: "'a set set" where "upsets = Fix \" abbreviation "downset_setp X \ X \ downsets" abbreviation "upset_setp X \ X \ upsets" definition ideals :: "'a set set" where "ideals = {X. X \ {} \ downset_setp X \ directed X}" definition filters :: "'a set set" where "filters = {X. X \ {} \ upset_setp X \ filtered X}" abbreviation "idealp X \ X \ ideals" abbreviation "filterp X \ X \ filters" end abbreviation Sup_pres :: "('a::Sup \ 'b::Sup) \ bool" where "Sup_pres f \ f \ Sup = Sup \ (`) f" abbreviation Inf_pres :: "('a::Inf \ 'b::Inf) \ bool" where "Inf_pres f \ f \ Inf = Inf \ (`) f" abbreviation sup_pres :: "('a::sup \ 'b::sup) \ bool" where "sup_pres f \ (\x y. f (x \ y) = f x \ f y)" abbreviation inf_pres :: "('a::inf \ 'b::inf) \ bool" where "inf_pres f \ (\x y. f (x \ y) = f x \ f y)" abbreviation bot_pres :: "('a::bot \ 'b::bot) \ bool" where "bot_pres f \ f \ = \" abbreviation top_pres :: "('a::top \ 'b::top) \ bool" where "top_pres f \ f \ = \" abbreviation Sup_dual :: "('a::Sup \ 'b::Inf) \ bool" where "Sup_dual f \ f \ Sup = Inf \ (`) f" abbreviation Inf_dual :: "('a::Inf \ 'b::Sup) \ bool" where "Inf_dual f \ f \ Inf = Sup \ (`) f" abbreviation sup_dual :: "('a::sup \ 'b::inf) \ bool" where "sup_dual f \ (\x y. f (x \ y) = f x \ f y)" abbreviation inf_dual :: "('a::inf \ 'b::sup) \ bool" where "inf_dual f \ (\x y. f (x \ y) = f x \ f y)" abbreviation bot_dual :: "('a::bot \ 'b::top) \ bool" where "bot_dual f \ f \ = \" abbreviation top_dual :: "('a::top \ 'b::bot) \ bool" where "top_dual f \ f \ = \" subsection \Duality via Locales\ sublocale ord \ dual_ord: ord "(\)" "(>)" rewrites dual_max_set: "max_set = dual_ord.min_set" and dual_filtered: "filtered = dual_ord.directed" and dual_upset_set: "upset_set = dual_ord.downset_set" and dual_upset: "upset = dual_ord.downset" and dual_upsets: "upsets = dual_ord.downsets" and dual_filters: "filters = dual_ord.ideals" apply unfold_locales unfolding max_set_def ord.min_set_def fun_eq_iff apply blast unfolding filtered_def ord.directed_def apply simp unfolding upset_set_def ord.downset_set_def apply simp apply (simp add: ord.downset_def ord.downset_set_def ord.upset_def ord.upset_set_def) unfolding upsets_def ord.downsets_def apply (metis ord.downset_set_def upset_set_def) unfolding filters_def ord.ideals_def Fix_def ord.downsets_def upsets_def ord.downset_set_def upset_set_def ord.directed_def filtered_def by simp sublocale preorder \ dual_preorder: preorder "(\)" "(>)" apply unfold_locales apply (simp add: less_le_not_le) apply simp using order_trans by blast sublocale order \ dual_order: order "(\)" "(>)" by (unfold_locales, simp) sublocale lattice \ dual_lattice: lattice sup "(\)" "(>)" inf by (unfold_locales, simp_all) sublocale bounded_lattice \ dual_bounded_lattice: bounded_lattice sup "(\)" "(>)" inf \ \ by (unfold_locales, simp_all) sublocale boolean_algebra \ dual_boolean_algebra: boolean_algebra "\x y. x \ -y" uminus sup "(\)" "(>)" inf \ \ by (unfold_locales, simp_all add: inf_sup_distrib1) sublocale complete_lattice \ dual_complete_lattice: complete_lattice Sup Inf sup "(\)" "(>)" inf \ \ rewrites dual_gfp: "gfp = dual_complete_lattice.lfp" proof- show "class.complete_lattice Sup Inf sup (\) (>) inf \ \" by (unfold_locales, simp_all add: Sup_upper Sup_least Inf_lower Inf_greatest) then interpret dual_complete_lattice: complete_lattice Sup Inf sup "(\)" "(>)" inf \ \. show "gfp = dual_complete_lattice.lfp" unfolding gfp_def dual_complete_lattice.lfp_def fun_eq_iff by simp qed context ord begin lemma dual_min_set: "min_set = dual_ord.max_set" by (simp add: dual_ord.dual_max_set) lemma dual_directed: "directed = dual_ord.filtered" by (simp add:dual_ord.dual_filtered) lemma dual_downset: "downset = dual_ord.upset" by (simp add: dual_ord.dual_upset) lemma dual_downset_set: "downset_set = dual_ord.upset_set" by (simp add: dual_ord.dual_upset_set) lemma dual_downsets: "downsets = dual_ord.upsets" by (simp add: dual_ord.dual_upsets) lemma dual_ideals: "ideals = dual_ord.filters" by (simp add: dual_ord.dual_filters) end context complete_lattice begin lemma dual_lfp: "lfp = dual_complete_lattice.gfp" by (simp add: dual_complete_lattice.dual_gfp) end subsection \Properties of Orderings, Again\ context ord begin lemma directed_nonempty: "directed X \ X \ {}" unfolding directed_def by fastforce lemma directed_ub: "directed X \ (\x \ X. \y \ X. \z \ X. x \ z \ y \ z)" by (meson empty_subsetI directed_def finite.emptyI finite_insert insert_subset order_refl) lemma downset_set_prop: "\ = Union \ (`) \" unfolding downset_set_def downset_def fun_eq_iff by fastforce lemma downset_set_prop_var: "\X = (\x \ X. \x)" by (simp add: downset_set_prop) lemma downset_prop: "\x = {y. y \ x}" unfolding downset_def downset_set_def fun_eq_iff comp_def by fastforce end context preorder begin lemma directed_prop: "X \ {} \ (\x \ X. \y \ X. \z \ X. x \ z \ y \ z) \ directed X" proof- assume h1: "X \ {}" and h2: "\x \ X. \y \ X. \z \ X. x \ z \ y \ z" {fix Y have "finite Y \ Y \ X \ (\x \ X. \y \ Y. y \ x)" proof (induct rule: finite_induct) case empty then show ?case using h1 by blast next case (insert x F) then show ?case by (metis h2 insert_iff insert_subset order_trans) qed} thus ?thesis by (simp add: directed_def) qed lemma directed_alt: "directed X = (X \ {} \ (\x \ X. \y \ X. \z \ X. x \ z \ y \ z))" by (metis directed_prop directed_nonempty directed_ub) lemma downset_set_ext: "id \ \" unfolding le_fun_def id_def downset_set_def by auto lemma downset_set_iso: "mono \" unfolding mono_def downset_set_def by blast lemma downset_set_idem [simp]: "\ \ \ = \" unfolding fun_eq_iff downset_set_def comp_def using order_trans by auto lemma downset_faithful: "\x \ \y \ x \ y" by (simp add: downset_prop subset_eq) lemma downset_iso_iff: "(\x \ \y) = (x \ y)" using atMost_iff downset_prop order_trans by blast lemma downset_directed_downset_var [simp]: "directed (\X) = directed X" proof assume h1: "directed X" {fix Y assume h2: "finite Y" and h3: "Y \ \X" hence "\y. \x. y \ Y \ x \ X \ y \ x" by (force simp: downset_set_def) hence "\f. \y. y \ Y \ f y \ X \ y \ f y" by (rule choice) hence "\f. finite (f ` Y) \ f ` Y \ X \ (\y \ Y. y \ f y)" by (metis finite_imageI h2 image_subsetI) hence "\Z. finite Z \ Z \ X \ (\y \ Y. \ z \ Z. y \ z)" by fastforce hence "\Z. finite Z \ Z \ X \ (\y \ Y. \ z \ Z. y \ z) \ (\x \ X. \ z \ Z. z \ x)" by (metis directed_def h1) hence "\x \ X. \y \ Y. y \ x" by (meson order_trans)} thus "directed (\X)" unfolding directed_def downset_set_def by fastforce next assume "directed (\X)" thus "directed X" unfolding directed_def downset_set_def apply clarsimp - by (smt Ball_Collect order_refl order_trans subsetCE) + by (smt (verit) Ball_Collect order_refl order_trans subsetCE) qed lemma downset_directed_downset [simp]: "directed \ \ = directed" unfolding fun_eq_iff comp_def by simp lemma directed_downset_ideals: "directed (\X) = (\X \ ideals)" by (metis (mono_tags, lifting) Fix_def comp_apply directed_alt downset_set_idem downsets_def ideals_def mem_Collect_eq) end lemma downset_iso: "mono (\::'a::order \ 'a set)" by (simp add: downset_iso_iff mono_def) context order begin lemma downset_inj: "inj \" by (metis injI downset_iso_iff order.eq_iff) end context lattice begin lemma lat_ideals: "X \ ideals = (X \ {} \ X \ downsets \ (\x \ X. \ y \ X. x \ y \ X))" unfolding ideals_def directed_alt downsets_def Fix_def downset_set_def - by (clarsimp, smt sup.cobounded1 sup.orderE sup.orderI sup_absorb2 sup_left_commute mem_Collect_eq) + using local.sup.bounded_iff by blast end context bounded_lattice begin lemma bot_ideal: "X \ ideals \ \ \ X" unfolding ideals_def downsets_def Fix_def downset_set_def by fastforce end context complete_lattice begin lemma Sup_downset_id [simp]: "Sup \ \ = id" using Sup_atMost atMost_def downset_prop by fastforce lemma downset_Sup_id: "id \ \ \ Sup" by (simp add: Sup_upper downset_prop le_funI subsetI) lemma Inf_Sup_var: "\(\x \ X. \x) = \X" unfolding downset_prop by (simp add: Collect_ball_eq Inf_eq_Sup) lemma Inf_pres_downset_var: "(\x \ X. \x) = \(\X)" unfolding downset_prop by (safe, simp_all add: le_Inf_iff) end lemma lfp_in_Fix: fixes f :: "'a::complete_lattice \ 'a" shows "mono f \ lfp f \ Fix f" using Fix_def lfp_unfold by fastforce lemma gfp_in_Fix: fixes f :: "'a::complete_lattice \ 'a" shows "mono f \ gfp f \ Fix f" using Fix_def gfp_unfold by fastforce lemma nonempty_Fix: fixes f :: "'a::complete_lattice \ 'a" shows "mono f \ Fix f \ {}" using lfp_in_Fix by fastforce subsection \Dual Properties of Orderings from Locales\ text \These properties can be proved very smoothly overall. But only within the context of a class or locale!\ context ord begin lemma filtered_nonempty: "filtered X \ X \ {}" by (simp add: dual_filtered dual_ord.directed_nonempty) lemma filtered_lb: "filtered X \ (\x \ X. \y \ X. \z \ X. z \ x \ z \ y)" by (simp add: dual_filtered dual_ord.directed_ub) lemma upset_set_prop: "\ = Union \ (`) \" by (simp add: dual_ord.downset_set_prop dual_upset dual_upset_set) lemma upset_set_prop_var: "\X = (\x \ X. \x)" by (simp add: dual_ord.downset_set_prop_var dual_upset dual_upset_set) lemma upset_prop: "\x = {y. x \ y}" by (simp add: dual_ord.downset_prop dual_upset) end context preorder begin lemma filtered_prop: "X \ {} \ (\x \ X. \y \ X. \z \ X. z \ x \ z \ y) \ filtered X" by (simp add: dual_filtered dual_preorder.directed_prop) lemma filtered_alt: "filtered X = (X \ {} \ (\x \ X. \y \ X. \z \ X. z \ x \ z \ y))" by (simp add: dual_filtered dual_preorder.directed_alt) lemma upset_set_ext: "id \ \" by (simp add: dual_preorder.downset_set_ext dual_upset_set) lemma upset_set_anti: "mono \" by (simp add: dual_preorder.downset_set_iso dual_upset_set) lemma up_set_idem [simp]: "\ \ \ = \" by (simp add: dual_upset_set) lemma upset_faithful: "\x \ \y \ y \ x" by (metis dual_preorder.downset_faithful dual_upset) lemma upset_anti_iff: "(\y \ \x) = (x \ y)" by (simp add: dual_preorder.downset_iso_iff dual_upset) lemma upset_filtered_upset [simp]: "filtered \ \ = filtered" by (simp add: dual_filtered dual_upset_set) lemma filtered_upset_filters: "filtered (\X) = (\X \ filters)" using dual_filtered dual_preorder.directed_downset_ideals dual_upset_set ord.dual_filters by fastforce end context order begin lemma upset_inj: "inj \" by (simp add: dual_order.downset_inj dual_upset) end context lattice begin lemma lat_filters: "X \ filters = (X \ {} \ X \ upsets \ (\x \ X. \ y \ X. x \ y \ X))" by (simp add: dual_filters dual_lattice.lat_ideals dual_ord.downsets_def dual_upset_set upsets_def) end context bounded_lattice begin lemma top_filter: "X \ filters \ \ \ X" by (simp add: dual_bounded_lattice.bot_ideal dual_filters) end context complete_lattice begin lemma Inf_upset_id [simp]: "Inf \ \ = id" by (simp add: dual_upset) lemma upset_Inf_id: "id \ \ \ Inf" by (simp add: dual_complete_lattice.downset_Sup_id dual_upset) lemma Sup_Inf_var: " \(\x \ X. \x) = \X" by (simp add: dual_complete_lattice.Inf_Sup_var dual_upset) lemma Sup_dual_upset_var: "(\x \ X. \x) = \(\X)" by (simp add: dual_complete_lattice.Inf_pres_downset_var dual_upset) end subsection \Examples that Do Not Dualise\ lemma upset_anti: "antimono (\::'a::order \ 'a set)" by (simp add: antimono_def upset_anti_iff) context complete_lattice begin lemma fSup_unfold: "(f::nat \ 'a) 0 \ (\n. f (Suc n)) = (\n. f n)" apply (intro order.antisym sup_least) apply (rule Sup_upper, force) apply (rule Sup_mono, force) apply (safe intro!: Sup_least) by (case_tac n, simp_all add: Sup_upper le_supI2) lemma fInf_unfold: "(f::nat \ 'a) 0 \ (\n. f (Suc n)) = (\n. f n)" apply (intro order.antisym inf_greatest) apply (rule Inf_greatest, safe) apply (case_tac n) apply simp_all using Inf_lower inf.coboundedI2 apply force apply (simp add: Inf_lower) by (auto intro: Inf_mono) end lemma fun_isol: "mono f \ mono ((\) f)" by (simp add: le_fun_def mono_def) lemma fun_isor: "mono f \ mono (\x. x \ f)" by (simp add: le_fun_def mono_def) lemma Sup_sup_pres: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "Sup_pres f \ sup_pres f" by (metis (no_types, opaque_lifting) Sup_empty Sup_insert comp_apply image_insert sup_bot.right_neutral) lemma Inf_inf_pres: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows"Inf_pres f \ inf_pres f" - by (smt INF_insert comp_eq_elim dual_complete_lattice.Sup_empty dual_complete_lattice.Sup_insert inf_top.right_neutral) + by (smt (verit) INF_insert comp_eq_elim dual_complete_lattice.Sup_empty dual_complete_lattice.Sup_insert inf_top.right_neutral) lemma Sup_bot_pres: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "Sup_pres f \ bot_pres f" by (metis SUP_empty Sup_empty comp_eq_elim) lemma Inf_top_pres: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "Inf_pres f \ top_pres f" by (metis INF_empty comp_eq_elim dual_complete_lattice.Sup_empty) context complete_lattice begin lemma iso_Inf_subdistl: assumes "mono (f::'a \ 'b::complete_lattice)" shows "f \ Inf \ Inf \ (`) f" by (simp add: assms complete_lattice_class.le_Inf_iff le_funI Inf_lower monoD) lemma iso_Sup_supdistl: assumes "mono (f::'a \ 'b::complete_lattice)" shows "Sup \ (`) f \ f \ Sup" by (simp add: assms complete_lattice_class.SUP_le_iff le_funI dual_complete_lattice.Inf_lower monoD) lemma Inf_subdistl_iso: fixes f :: "'a \ 'b::complete_lattice" shows "f \ Inf \ Inf \ (`) f \ mono f" unfolding mono_def le_fun_def comp_def by (metis complete_lattice_class.le_INF_iff Inf_atLeast atLeast_iff) lemma Sup_supdistl_iso: fixes f :: "'a \ 'b::complete_lattice" shows "Sup \ (`) f \ f \ Sup \ mono f" unfolding mono_def le_fun_def comp_def by (metis complete_lattice_class.SUP_le_iff Sup_atMost atMost_iff) lemma supdistl_iso: fixes f :: "'a \ 'b::complete_lattice" shows "(Sup \ (`) f \ f \ Sup) = mono f" using Sup_supdistl_iso iso_Sup_supdistl by force lemma subdistl_iso: fixes f :: "'a \ 'b::complete_lattice" shows "(f \ Inf \ Inf \ (`) f) = mono f" using Inf_subdistl_iso iso_Inf_subdistl by force end lemma fSup_distr: "Sup_pres (\x. x \ f)" unfolding fun_eq_iff comp_def - by (smt Inf.INF_cong SUP_apply Sup_apply) + by (smt (verit) Inf.INF_cong SUP_apply Sup_apply) lemma fSup_distr_var: "\F \ g = (\f \ F. f \ g)" unfolding fun_eq_iff comp_def - by (smt Inf.INF_cong SUP_apply Sup_apply) + by (smt (verit) Inf.INF_cong SUP_apply Sup_apply) lemma fInf_distr: "Inf_pres (\x. x \ f)" unfolding fun_eq_iff comp_def - by (smt INF_apply Inf.INF_cong Inf_apply) + by (smt (verit) INF_apply Inf.INF_cong Inf_apply) lemma fInf_distr_var: "\F \ g = (\f \ F. f \ g)" unfolding fun_eq_iff comp_def - by (smt INF_apply Inf.INF_cong Inf_apply) + by (smt (verit) INF_apply Inf.INF_cong Inf_apply) lemma fSup_subdistl: assumes "mono (f::'a::complete_lattice \ 'b::complete_lattice)" shows "Sup \ (`) ((\) f) \ (\) f \ Sup" using assms by (simp add: SUP_least Sup_upper le_fun_def monoD image_comp) lemma fSup_subdistl_var: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "mono f \ (\g \ G. f \ g) \ f \ \G" by (simp add: SUP_least Sup_upper le_fun_def monoD image_comp) lemma fInf_subdistl: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "mono f \ (\) f \ Inf \ Inf \ (`) ((\) f)" by (simp add: INF_greatest Inf_lower le_fun_def monoD image_comp) lemma fInf_subdistl_var: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "mono f \ f \ \G \ (\g \ G. f \ g)" by (simp add: INF_greatest Inf_lower le_fun_def monoD image_comp) lemma Inf_pres_downset: "Inf_pres (\::'a::complete_lattice \ 'a set)" unfolding downset_prop fun_eq_iff comp_def by (safe, simp_all add: le_Inf_iff) lemma Sup_dual_upset: "Sup_dual (\::'a::complete_lattice \ 'a set)" unfolding upset_prop fun_eq_iff comp_def by (safe, simp_all add: Sup_le_iff) text \This approach could probably be combined with the explicit functor-based one. This may be good for proofs, but seems conceptually rather ugly.\ end \ No newline at end of file diff --git a/thys/Order_Lattice_Props/Representations.thy b/thys/Order_Lattice_Props/Representations.thy --- a/thys/Order_Lattice_Props/Representations.thy +++ b/thys/Order_Lattice_Props/Representations.thy @@ -1,620 +1,621 @@ (* Title: Representation Theorems for Orderings and Lattices Author: Georg Struth Maintainer: Georg Struth *) section \Representation Theorems for Orderings and Lattices\ theory Representations imports Order_Lattice_Props begin subsection \Representation of Posets\ text \The isomorphism between partial orders and downsets with set inclusion is well known. It forms the basis of Priestley and Stone duality. I show it not only for objects, but also order morphisms, hence establish equivalences and isomorphisms between categories.\ typedef (overloaded) 'a downset = "range (\::'a::ord \ 'a set)" by fastforce setup_lifting type_definition_downset text \The map ds yields the isomorphism between the set and the powerset level if its range is restricted to downsets.\ definition ds :: "'a::ord \ 'a downset" where "ds = Abs_downset \ \" text \In a complete lattice, its inverse is Sup.\ definition SSup :: "'a::complete_lattice downset \ 'a" where "SSup = Sup \ Rep_downset" lemma ds_SSup_inv: "ds \ SSup = (id::'a::complete_lattice downset \ 'a downset)" unfolding ds_def SSup_def - by (smt Rep_downset Rep_downset_inverse cSup_atMost eq_id_iff imageE o_def ord_class.atMost_def ord_class.downset_prop) + by (smt (verit) Rep_downset Rep_downset_inverse cSup_atMost eq_id_iff imageE o_def ord_class.atMost_def ord_class.downset_prop) lemma SSup_ds_inv: "SSup \ ds = (id::'a::complete_lattice \ 'a)" unfolding ds_def SSup_def fun_eq_iff id_def comp_def by (simp add: Abs_downset_inverse pointfree_idE) instantiation downset :: (ord) order begin lift_definition less_eq_downset :: "'a downset \ 'a downset \ bool" is "(\X Y. Rep_downset X \ Rep_downset Y)" . lift_definition less_downset :: "'a downset \ 'a downset \ bool" is "(\X Y. Rep_downset X \ Rep_downset Y)" . instance by (intro_classes, transfer, auto simp: Rep_downset_inject less_eq_downset_def) end lemma ds_iso: "mono ds" unfolding mono_def ds_def fun_eq_iff comp_def by (metis Abs_downset_inverse downset_iso_iff less_eq_downset.rep_eq rangeI) lemma ds_faithful: "ds x \ ds y \ x \ (y::'a::order)" by (simp add: Abs_downset_inverse downset_faithful ds_def less_eq_downset.rep_eq) lemma ds_inj: "inj (ds::'a::order \ 'a downset)" by (simp add: ds_faithful dual_order.antisym injI) lemma ds_surj: "surj ds" by (metis (no_types, opaque_lifting) Rep_downset Rep_downset_inverse ds_def image_iff o_apply surj_def) lemma ds_bij: "bij (ds::'a::order \ 'a downset)" by (simp add: bijI ds_inj ds_surj) lemma ds_ord_iso: "ord_iso ds" - unfolding ord_iso_def comp_def inf_bool_def by (smt UNIV_I ds_bij ds_faithful ds_inj ds_iso ds_surj f_the_inv_into_f inf1I mono_def) + unfolding ord_iso_def comp_def inf_bool_def by (smt (verit) UNIV_I ds_bij ds_faithful ds_inj ds_iso ds_surj f_the_inv_into_f inf1I mono_def) text \The morphishms between orderings and downsets are isotone functions. One can define functors mapping back and forth between these.\ definition map_ds :: "('a::complete_lattice \ 'b::complete_lattice) \ ('a downset \ 'b downset)" where "map_ds f = ds \ f \ SSup" text \This definition is actually contrived. We have shown that a function f between posets P and Q is isotone if and only if the inverse image of f maps downclosed sets in Q to downclosed sets in P. There is the following duality: ds is a natural transformation between the identity functor and the preimage functor as a contravariant functor from P to Q. Hence orderings with isotone maps and downsets with downset-preserving maps are dual, which is a first step towards Stone duality. I don't see a way of proving this with Isabelle, as the types of the preimage of f are the wrong way and I don't see how I could capture opposition with what I have.\ (*lemma "mono (f::'a::complete_lattice \ 'b::complete_lattimap_ds f = Abs_downset \ (-`) f \ Rep_downset" doesn't work! *) lemma map_ds_prop: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "map_ds f \ ds = ds \ f" unfolding map_ds_def by (simp add: SSup_ds_inv comp_assoc) lemma map_ds_prop2: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "map_ds f \ ds = ds \ id f" unfolding map_ds_def by (simp add: SSup_ds_inv comp_assoc) text \This is part of showing that map-ds is naturally isomorphic to the identity functor, ds being the natural isomorphism.\ definition map_SSup :: "('a downset \ 'b downset) \ ('a::complete_lattice \ 'b::complete_lattice)" where "map_SSup F = SSup \ F \ ds" lemma map_ds_iso_pres: fixes f :: "'a::complete_lattice \ 'b::complete_lattice" shows "mono f \ mono (map_ds f)" unfolding fun_eq_iff mono_def map_ds_def ds_def SSup_def comp_def by (metis Abs_downset_inverse Sup_subset_mono downset_iso_iff less_eq_downset.rep_eq rangeI) lemma map_SSup_iso_pres: fixes F :: "'a::complete_lattice downset \ 'b::complete_lattice downset" shows "mono F \ mono (map_SSup F)" unfolding fun_eq_iff mono_def map_SSup_def ds_def SSup_def comp_def by (metis Abs_downset_inverse Sup_subset_mono downset_iso_iff less_eq_downset.rep_eq rangeI) lemma map_SSup_prop: fixes F :: "'a::complete_lattice downset \ 'b::complete_lattice downset" shows "ds \ map_SSup F = F \ ds" unfolding map_SSup_def by (metis ds_SSup_inv fun.map_id0 id_def rewriteL_comp_comp) lemma map_SSup_prop2: fixes F :: "'a::complete_lattice downset \ 'b::complete_lattice downset" shows "ds \ map_SSup F = id F \ ds" by (simp add: map_SSup_prop) lemma map_ds_func1: "map_ds id = (id::'a::complete_lattice downset\ 'a downset)" by (simp add: ds_SSup_inv map_ds_def) lemma map_ds_func2: fixes g :: "'a::complete_lattice \ 'b::complete_lattice" shows "map_ds (f \ g) = map_ds f \ map_ds g" unfolding map_ds_def fun_eq_iff comp_def ds_def SSup_def by (metis Abs_downset_inverse Sup_atMost atMost_def downset_prop rangeI) lemma map_SSup_func1: "map_SSup (id::'a::complete_lattice downset\ 'a downset) = id" by (simp add: SSup_ds_inv map_SSup_def) lemma map_SSup_func2: fixes F :: "'c::complete_lattice downset \ 'b::complete_lattice downset" and G :: "'a::complete_lattice downset \ 'c downset" shows "map_SSup (F \ G) = map_SSup F \ map_SSup G" unfolding map_SSup_def fun_eq_iff comp_def id_def ds_def by (metis comp_apply ds_SSup_inv ds_def id_apply) lemma map_SSup_map_ds_inv: "map_SSup \ map_ds = (id::('a::complete_lattice \ 'b::complete_lattice) \ ('a \ 'b))" by (metis (no_types, opaque_lifting) SSup_ds_inv comp_def eq_id_iff fun.map_comp fun.map_id0 id_apply map_SSup_prop map_ds_prop) lemma map_ds_map_SSup_inv: "map_ds \ map_SSup = (id::('a::complete_lattice downset \ 'b::complete_lattice downset) \ ('a downset \ 'b downset))" unfolding map_SSup_def map_ds_def SSup_def ds_def id_def comp_def fun_eq_iff by (metis (no_types, lifting) Rep_downset Rep_downset_inverse Sup_downset_id image_iff pointfree_idE) lemma inj_map_ds: "inj (map_ds::('a::complete_lattice \ 'b::complete_lattice) \ ('a downset \ 'b downset))" by (metis (no_types, lifting) SSup_ds_inv fun.map_id0 id_comp inj_def map_ds_prop rewriteR_comp_comp2) lemma inj_map_SSup: "inj (map_SSup::('a::complete_lattice downset \ 'b::complete_lattice downset) \ ('a \ 'b))" by (metis inj_on_id inj_on_imageI2 map_ds_map_SSup_inv) lemma map_ds_map_SSup_iff: fixes g :: "'a::complete_lattice \ 'b::complete_lattice" shows "(f = map_ds g) = (map_SSup f = g)" by (metis inj_eq inj_map_ds map_ds_map_SSup_inv pointfree_idE) text \This gives an isomorphism between categories.\ lemma surj_map_ds: "surj (map_ds::('a::complete_lattice \ 'b::complete_lattice) \ ('a downset \ 'b downset))" by (simp add: map_ds_map_SSup_iff surj_def) lemma surj_map_SSup: "surj (map_SSup::('a::complete_lattice_with_dual downset \ 'b::complete_lattice_with_dual downset) \ ('a \ 'b))" by (metis map_ds_map_SSup_iff surjI) text \There is of course a dual result for upsets with the reverse inclusion ordering. Once again, it seems impossible to capture the "real" duality that uses the inverse image functor.\ typedef (overloaded) 'a upset = "range (\::'a::ord \ 'a set)" by fastforce setup_lifting type_definition_upset definition us :: "'a::ord \ 'a upset" where "us = Abs_upset \ \" definition IInf :: "'a::complete_lattice upset \ 'a" where "IInf = Inf \ Rep_upset" lemma us_ds: "us = Abs_upset \ (`) \ \ Rep_downset \ ds \ (\::'a::ord_with_dual \ 'a)" unfolding us_def ds_def fun_eq_iff comp_def by (simp add: Abs_downset_inverse upset_to_downset2) lemma IInf_SSup: "IInf = \ \ SSup \ Abs_downset \ (`) (\::'a::complete_lattice_with_dual \ 'a) \ Rep_upset" unfolding IInf_def SSup_def fun_eq_iff comp_def by (metis (no_types, opaque_lifting) Abs_downset_inverse Rep_upset Sup_dual_def_var image_iff rangeI subset_dual upset_to_downset3) lemma us_IInf_inv: "us \ IInf = (id::'a::complete_lattice_with_dual upset \ 'a upset)" unfolding us_def IInf_def fun_eq_iff id_def comp_def by (metis (no_types, lifting) Inf_upset_id Rep_upset Rep_upset_inverse f_the_inv_into_f pointfree_idE upset_inj) lemma IInf_us_inv: "IInf \ us = (id::'a::complete_lattice_with_dual \ 'a)" unfolding us_def IInf_def fun_eq_iff id_def comp_def by (metis Abs_upset_inverse Sup_Inf_var Sup_atLeastAtMost Sup_dual_upset_var order_refl rangeI) instantiation upset :: (ord) order begin lift_definition less_eq_upset :: "'a upset \ 'a upset \ bool" is "(\X Y. Rep_upset X \ Rep_upset Y)" . lift_definition less_upset :: "'a upset \ 'a upset \ bool" is "(\X Y. Rep_upset X \ Rep_upset Y)" . instance by (intro_classes, transfer, simp_all add: less_le_not_le less_eq_upset.rep_eq Rep_upset_inject) end lemma us_iso: "x \ y \ us x \ us (y::'a::order_with_dual)" by (simp add: Abs_upset_inverse less_eq_upset.rep_eq upset_anti_iff us_def) lemma us_faithful: "us x \ us y \ x \ (y::'a::order_with_dual)" by (simp add: Abs_upset_inverse upset_faithful us_def less_eq_upset.rep_eq) lemma us_inj: "inj (us::'a::order_with_dual \ 'a upset)" unfolding inj_def by (simp add: us_faithful dual_order.antisym) lemma us_surj: "surj (us::'a::order_with_dual \ 'a upset)" unfolding surj_def by (metis Rep_upset Rep_upset_inverse comp_def image_iff us_def) lemma us_bij: "bij (us::'a::order_with_dual \ 'a upset)" by (simp add: bij_def us_surj us_inj) lemma us_ord_iso: "ord_iso (us::'a::order_with_dual \ 'a upset)" unfolding ord_iso_def by (simp, metis (no_types, lifting) UNIV_I f_the_inv_into_f monoI us_iso us_bij us_faithful us_inj us_surj) definition map_us :: "('a::complete_lattice \ 'b::complete_lattice) \ ('a upset \ 'b upset)" where "map_us f = us \ f \ IInf" lemma map_us_prop: "map_us f \ (us::'a::complete_lattice_with_dual \ 'a upset) = us \ id f" unfolding map_us_def by (simp add: IInf_us_inv comp_assoc) definition map_IInf :: "('a upset \ 'b upset) \ ('a::complete_lattice \ 'b::complete_lattice)" where "map_IInf F = IInf \ F \ us" lemma map_IInf_prop: "(us::'a::complete_lattice_with_dual \ 'a upset) \ map_IInf F = id F \ us" proof- have "us \ map_IInf F = (us \ IInf) \ F \ us" by (simp add: fun.map_comp map_IInf_def) thus ?thesis by (simp add: us_IInf_inv) qed lemma map_us_func1: "map_us id = (id::'a::complete_lattice_with_dual upset \ 'a upset)" unfolding map_us_def fun_eq_iff comp_def us_def id_def IInf_def by (metis (no_types, lifting) Inf_upset_id Rep_upset Rep_upset_inverse image_iff pointfree_idE) lemma map_us_func2: fixes f :: "'c::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" and g :: "'a::complete_lattice_with_dual \ 'c" shows "map_us (f \ g) = map_us f \ map_us g" unfolding map_us_def fun_eq_iff comp_def us_def IInf_def by (metis Abs_upset_inverse Sup_Inf_var Sup_atLeastAtMost Sup_dual_upset_var order_refl rangeI) lemma map_IInf_func1: "map_IInf id = (id::'a::complete_lattice_with_dual \ 'a)" unfolding map_IInf_def fun_eq_iff comp_def id_def us_def IInf_def by (simp add: Abs_upset_inverse pointfree_idE) lemma map_IInf_func2: fixes F :: "'c::complete_lattice_with_dual upset \ 'b::complete_lattice_with_dual upset" and G :: "'a::complete_lattice_with_dual upset \ 'c upset" shows "map_IInf (F \ G) = map_IInf F \ map_IInf G" unfolding map_IInf_def fun_eq_iff comp_def id_def us_def by (metis comp_apply id_apply us_IInf_inv us_def) lemma map_IInf_map_us_inv: "map_IInf \ map_us = (id::('a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual) \ ('a \ 'b))" unfolding map_IInf_def map_us_def IInf_def us_def id_def comp_def fun_eq_iff by (simp add: Abs_upset_inverse pointfree_idE) lemma map_us_map_IInf_inv: "map_us \ map_IInf = (id::('a::complete_lattice_with_dual upset \ 'b::complete_lattice_with_dual upset) \ ('a upset \ 'b upset))" unfolding map_IInf_def map_us_def IInf_def us_def id_def comp_def fun_eq_iff by (metis (no_types, lifting) Inf_upset_id Rep_upset Rep_upset_inverse image_iff pointfree_idE) lemma inj_map_us: "inj (map_us::('a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual) \ ('a upset \ 'b upset))" unfolding map_us_def us_def IInf_def inj_def comp_def fun_eq_iff by (metis (no_types, opaque_lifting) Abs_upset_inverse Inf_upset_id pointfree_idE rangeI) lemma inj_map_IInf: "inj (map_IInf::('a::complete_lattice_with_dual upset \ 'b::complete_lattice_with_dual upset) \ ('a \ 'b))" unfolding map_IInf_def fun_eq_iff inj_def comp_def IInf_def us_def by (metis (no_types, opaque_lifting) Inf_upset_id Rep_upset Rep_upset_inverse image_iff pointfree_idE) lemma map_us_map_IInf_iff: fixes g :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" shows "(f = map_us g) = (map_IInf f = g)" by (metis inj_eq inj_map_us map_us_map_IInf_inv pointfree_idE) lemma map_us_mono_pres: fixes f :: "'a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual" shows "mono f \ mono (map_us f)" unfolding mono_def map_us_def comp_def us_def IInf_def by (metis Abs_upset_inverse Inf_superset_mono less_eq_upset.rep_eq rangeI upset_anti_iff) lemma map_IInf_mono_pres: fixes F :: "'a::complete_lattice_with_dual upset \ 'b::complete_lattice_with_dual upset" shows "mono F \ mono (map_IInf F)" unfolding mono_def map_IInf_def comp_def us_def IInf_def oops lemma surj_map_us: "surj (map_us::('a::complete_lattice_with_dual \ 'b::complete_lattice_with_dual) \ ('a upset \ 'b upset))" by (simp add: map_us_map_IInf_iff surj_def) lemma surj_map_IInf: "surj (map_IInf::('a::complete_lattice_with_dual upset \ 'b::complete_lattice_with_dual upset) \ ('a \ 'b))" by (metis map_us_map_IInf_iff surjI) text \Hence we have again an isomorphism --- or rather equivalence --- between categories. Here, however, duality is not consistently picked up.\ subsection \Stone's Theorem in the Presence of Atoms\ text \Atom-map is a boolean algebra morphism.\ context boolean_algebra begin lemma atom_map_compl_pres: "atom_map (-x) = Collect atom - atom_map x" proof- {fix y have "(y \ atom_map (-x)) = (atom y \ y \ -x)" by (simp add: atom_map_def) also have "... = (atom y \ \(y \ x))" by (metis atom_sup_iff inf.orderE inf_shunt sup_compl_top top.ordering_top_axioms ordering_top.extremum) also have "... = (y \ Collect atom - atom_map x)" using atom_map_def by auto finally have "(y \ atom_map (-x)) = (y \ Collect atom - atom_map x)".} thus ?thesis by blast qed lemma atom_map_sup_pres: "atom_map (x \ y) = atom_map x \ atom_map y" proof- {fix z have "(z \ atom_map (x \ y)) = (atom z \ z \ x \ y)" by (simp add: atom_map_def) also have "... = (atom z \ (z \ x \ z \ y))" using atom_sup_iff by auto also have "... = (z \ atom_map x \ atom_map y)" using atom_map_def by auto finally have "(z \ atom_map (x \ y)) = (z \ atom_map x \ atom_map y)" by blast} thus ?thesis by blast qed lemma atom_map_inf_pres: "atom_map (x \ y) = atom_map x \ atom_map y" - by (smt Diff_Un atom_map_compl_pres atom_map_sup_pres compl_inf double_compl) + by (smt (verit) Diff_Un atom_map_compl_pres atom_map_sup_pres compl_inf double_compl) lemma atom_map_minus_pres: "atom_map (x - y) = atom_map x - atom_map y" using atom_map_compl_pres atom_map_def diff_eq by auto end text \The homomorphic images of boolean algebras under atom-map are boolean algebras --- in fact powerset boolean algebras.\ instantiation atoms :: (boolean_algebra) boolean_algebra begin lift_definition minus_atoms :: "'a atoms \ 'a atoms \ 'a atoms" is "\x y. Abs_atoms (Rep_atoms x - Rep_atoms y)". lift_definition uminus_atoms :: "'a atoms \ 'a atoms" is "\x. Abs_atoms (Collect atom - Rep_atoms x)". lift_definition bot_atoms :: "'a atoms" is "Abs_atoms {}". lift_definition sup_atoms :: "'a atoms \ 'a atoms \ 'a atoms" is "\x y. Abs_atoms (Rep_atoms x \ Rep_atoms y)". lift_definition top_atoms :: "'a atoms" is "Abs_atoms (Collect atom)". lift_definition inf_atoms :: "'a atoms \ 'a atoms \ 'a atoms" is "\x y. Abs_atoms (Rep_atoms x \ Rep_atoms y)". lift_definition less_eq_atoms :: "'a atoms \ 'a atoms \ bool" is "(\x y. Rep_atoms x \ Rep_atoms y)". lift_definition less_atoms :: "'a atoms \ 'a atoms \ bool" is "(\x y. Rep_atoms x \ Rep_atoms y)". instance apply intro_classes apply (transfer, simp add: less_le_not_le) apply (transfer, simp) apply (transfer, blast) apply (simp add: Rep_atoms_inject less_eq_atoms.abs_eq) - apply (transfer, smt Abs_atoms_inverse Rep_atoms atom_map_inf_pres image_iff inf_le1 rangeI) - apply (transfer, smt Abs_atoms_inverse Rep_atoms atom_map_inf_pres image_iff inf_le2 rangeI) - apply (transfer, smt Abs_atoms_inverse Rep_atoms atom_map_inf_pres image_iff le_iff_sup rangeI sup_inf_distrib1) - apply (transfer, smt Abs_atoms_inverse Rep_atoms atom_map_sup_pres image_iff image_iff inf.orderE inf_sup_aci(6) le_iff_sup order_refl rangeI rangeI) - apply (transfer, smt Abs_atoms_inverse Rep_atoms atom_map_sup_pres image_iff inf_sup_aci(6) le_iff_sup rangeI sup.left_commute sup.right_idem) + apply (transfer, smt (verit) Abs_atoms_inverse Rep_atoms atom_map_inf_pres image_iff inf_le1 rangeI) + apply (transfer, smt (verit) Abs_atoms_inverse Rep_atoms atom_map_inf_pres image_iff inf_le2 rangeI) + apply (transfer, smt (verit) Abs_atoms_inverse Rep_atoms atom_map_inf_pres image_iff le_iff_sup rangeI sup_inf_distrib1) + apply (transfer, smt (verit) Abs_atoms_inverse Rep_atoms atom_map_sup_pres image_iff image_iff inf.orderE inf_sup_aci(6) le_iff_sup order_refl rangeI rangeI) + apply (transfer, smt (verit) Abs_atoms_inverse Rep_atoms atom_map_sup_pres image_iff inf_sup_aci(6) le_iff_sup rangeI sup.left_commute sup.right_idem) apply (transfer, subst Abs_atoms_inverse, metis (no_types, lifting) Rep_atoms atom_map_sup_pres image_iff rangeI, simp) apply transfer using Abs_atoms_inverse atom_map_bot_pres apply blast apply (transfer, metis Abs_atoms_inverse Rep_atoms atom_map_compl_pres atom_map_top_pres diff_eq double_compl inf_le1 rangeE rangeI) - apply (transfer, smt Abs_atoms_inverse Rep_atoms atom_map_inf_pres atom_map_sup_pres image_iff rangeI sup_inf_distrib1) + apply (transfer, smt (verit, ccfv_threshold) Abs_atoms_inverse Rep_atoms atom_map_inf_pres atom_map_sup_pres image_iff rangeI sup_inf_distrib1) apply (transfer, metis (no_types, opaque_lifting) Abs_atoms_inverse Diff_disjoint Rep_atoms atom_map_compl_pres rangeE rangeI) apply (transfer, smt Abs_atoms_inverse uminus_atoms.abs_eq Rep_atoms Un_Diff_cancel atom_map_compl_pres atom_map_inf_pres atom_map_minus_pres atom_map_sup_pres atom_map_top_pres diff_eq double_compl inf_compl_bot_right rangeE rangeI sup_commute sup_compl_top) - by transfer (smt Abs_atoms_inverse Rep_atoms atom_map_compl_pres atom_map_inf_pres atom_map_minus_pres diff_eq rangeE rangeI) + apply (transfer, smt Abs_atoms_inverse Rep_atoms atom_map_compl_pres atom_map_inf_pres atom_map_minus_pres diff_eq rangeE rangeI) + done end text \The homomorphism atom-map can then be restricted in its output type to the powerset boolean algebra.\ lemma at_map_bot_pres: "at_map \ = \" by (simp add: at_map_def atom_map_bot_pres bot_atoms.transfer) lemma at_map_top_pres: "at_map \ = \" by (simp add: at_map_def atom_map_top_pres top_atoms.transfer) lemma at_map_compl_pres: "at_map \ uminus = uminus \ at_map" unfolding fun_eq_iff by (simp add: Abs_atoms_inverse at_map_def atom_map_compl_pres uminus_atoms.abs_eq) lemma at_map_sup_pres: "at_map (x \ y) = at_map x \ at_map y" unfolding at_map_def comp_def by (metis (mono_tags, lifting) Abs_atoms_inverse atom_map_sup_pres rangeI sup_atoms.transfer) lemma at_map_inf_pres: "at_map (x \ y) = at_map x \ at_map y" unfolding at_map_def comp_def by (metis (mono_tags, lifting) Abs_atoms_inverse atom_map_inf_pres inf_atoms.transfer rangeI) lemma at_map_minus_pres: "at_map (x - y) = at_map x - at_map y" unfolding at_map_def comp_def by (simp add: Abs_atoms_inverse atom_map_minus_pres minus_atoms.abs_eq) context atomic_boolean_algebra begin text \In atomic boolean algebras, atom-map is an embedding that maps atoms of the boolean algebra to those of the powerset boolean algebra. Analogous properties hold for at-map.\ lemma inj_atom_map: "inj atom_map" proof- {fix x y ::'a assume "x \ y" hence "x \ -y \ \ \ -x \ y \ \" by (auto simp: inf_shunt) hence "\z. atom z \ (z \ x \ -y \ z \ -x \ y)" using atomicity by blast hence "\z. atom z \ ((z \ atom_map x \ \(z \ atom_map y)) \ (\(z \ atom_map x) \ z \ atom_map y))" unfolding atom_def atom_map_def by (clarsimp, metis diff_eq inf.orderE diff_shunt_var) hence "atom_map x \ atom_map y" by blast} thus ?thesis by (meson injI) qed lemma atom_map_atom_pres: "atom x \ atom_map x = {x}" unfolding atom_def atom_map_def by (auto simp: bot_less dual_order.order_iff_strict) lemma atom_map_atom_pres2: "atom x \ atom (atom_map x)" proof- assume "atom x" hence "atom_map x = {x}" by (simp add: atom_map_atom_pres) thus "atom (atom_map x)" using bounded_lattice_class.atom_def by auto qed end lemma inj_at_map: "inj (at_map::'a::atomic_boolean_algebra \ 'a atoms)" unfolding at_map_def comp_def by (metis (no_types, lifting) Abs_atoms_inverse inj_atom_map inj_def rangeI) lemma at_map_atom_pres: "atom (x::'a::atomic_boolean_algebra) \ at_map x = Abs_atoms {x}" unfolding at_map_def comp_def by (simp add: atom_map_atom_pres) lemma at_map_atom_pres2: "atom (x::'a::atomic_boolean_algebra) \ atom (at_map x)" unfolding at_map_def comp_def by (metis Abs_atoms_inverse atom_def atom_map_atom_pres2 atom_map_bot_pres bot_atoms.abs_eq less_atoms.abs_eq rangeI) text \Homomorphic images of atomic boolean algebras under atom-map are therefore atomic (rather obviously).\ instance atoms :: (atomic_boolean_algebra) atomic_boolean_algebra proof intro_classes fix x::"'a atoms" assume "x \ \" hence "\y. x = at_map y \ x \ \" unfolding at_map_def comp_def by (metis Abs_atoms_cases rangeE) hence "\y. x = at_map y \ (\z. atom z \ z \ y)" using at_map_bot_pres atomicity by force hence "\y. x = at_map y \ (\z. atom (at_map z) \ at_map z \ at_map y)" by (metis at_map_atom_pres2 at_map_sup_pres sup.orderE sup_ge2) thus "\y. atom y \ y \ x" by fastforce qed context complete_boolean_algebra_alt begin text \In complete boolean algebras, atom-map is surjective; more precisely it is the left inverse of Sup, at least for sets of atoms. Below, this statement is made more explicit for at-map.\ lemma surj_atom_map: "Y \ Collect atom \ Y = atom_map (\Y)" proof assume "Y \ Collect atom" thus "Y \ atom_map (\Y)" using Sup_upper atom_map_def by force next assume "Y \ Collect atom" hence a: "\y. y \ Y \ atom y" by blast {fix z assume h: "z \ Collect atom - Y" hence "\y \ Y. y \ z = \" by (metis DiffE a h atom_def dual_order.not_eq_order_implies_strict inf.absorb_iff2 inf_le2 inf_shunt mem_Collect_eq) hence "\Y \ z = \" using Sup_least inf_shunt by simp hence "z \ atom_map (\Y)" using atom_map_bot_pres atom_map_def by force} thus "atom_map (\Y) \ Y" using atom_map_def by force qed text \In this setting, atom-map is a complete boolean algebra morphism.\ lemma atom_map_Sup_pres: "atom_map (\X) = (\x \ X. atom_map x)" proof- {fix z have "(z \ atom_map (\X)) = (atom z \ z \ \X)" by (simp add: atom_map_def) also have "... = (atom z \ (\x \ X. z \ x))" using atom_Sup_iff by auto also have "... = (z \ (\x \ X. atom_map x))" using atom_map_def by auto finally have "(z \ atom_map (\X)) = (z \ (\x \ X. atom_map x))" by blast} thus ?thesis by blast qed lemma atom_map_Sup_pres_var: "atom_map \ Sup = Sup \ (`) atom_map" unfolding fun_eq_iff comp_def by (simp add: atom_map_Sup_pres) text \For Inf-preservation, it is important that Infs are restricted to homomorphic images; hence they need to be pushed into the set of all atoms.\ lemma atom_map_Inf_pres: "atom_map (\X) = Collect atom \ (\x \ X. atom_map x)" proof- have "atom_map (\X) = atom_map (-(\x \ X. -x))" by (smt Collect_cong SUP_le_iff atom_map_def compl_le_compl_iff compl_le_swap1 le_Inf_iff) also have "... = Collect atom - atom_map (\x \ X. -x)" using atom_map_compl_pres by blast also have "... = Collect atom - (\x \ X. atom_map (-x))" by (simp add: atom_map_Sup_pres) also have "... = Collect atom - (\x \ X. Collect atom - atom_map (x))" using atom_map_compl_pres by blast also have "... = Collect atom \ (\x \ X. atom_map x)" by blast finally show ?thesis. qed end text \It follows that homomorphic images of complete boolean algebras under atom-map form complete boolean algebras.\ instantiation atoms :: (complete_boolean_algebra_alt) complete_boolean_algebra_alt begin lift_definition Inf_atoms :: "'a::complete_boolean_algebra_alt atoms set \ 'a::complete_boolean_algebra_alt atoms" is "\X. Abs_atoms (Collect atom \ Inter ((`) Rep_atoms X))". lift_definition Sup_atoms :: "'a::complete_boolean_algebra_alt atoms set \ 'a::complete_boolean_algebra_alt atoms" is "\X. Abs_atoms (Union ((`) Rep_atoms X))". instance apply (intro_classes; transfer) apply (metis (no_types, opaque_lifting) Abs_atoms_inverse image_iff inf_le1 le_Inf_iff le_infI2 order_refl rangeI surj_atom_map) apply (metis (no_types, lifting) Abs_atoms_inverse Int_subset_iff Rep_atoms Sup_upper atom_map_atoms inf_le1 le_INF_iff rangeI surj_atom_map) apply (metis Abs_atoms_inverse Rep_atoms SUP_least SUP_upper Sup_upper atom_map_atoms rangeI surj_atom_map) apply (metis Abs_atoms_inverse Rep_atoms SUP_least Sup_upper atom_map_atoms rangeI surj_atom_map) by simp_all end text \Once more, properties proved above can now be restricted to at-map.\ lemma surj_at_map_var: "at_map \ Sup \ Rep_atoms = (id::'a::complete_boolean_algebra_alt atoms \ 'a atoms)" unfolding at_map_def comp_def fun_eq_iff id_def by (metis Rep_atoms Rep_atoms_inverse Sup_upper atom_map_atoms surj_atom_map) lemma surj_at_map: "surj (at_map::'a::complete_boolean_algebra_alt \ 'a atoms)" unfolding surj_def at_map_def comp_def by (metis Rep_atoms Rep_atoms_inverse image_iff) lemma at_map_Sup_pres: "at_map \ Sup = Sup \ (`) (at_map::'a::complete_boolean_algebra_alt \ 'a atoms)" unfolding fun_eq_iff at_map_def comp_def atom_map_Sup_pres by (smt Abs_atoms_inverse Sup.SUP_cong Sup_atoms.transfer UN_extend_simps(10) rangeI) lemma at_map_Sup_pres_var: "at_map (\X) = (\(x::'a::complete_boolean_algebra_alt) \ X. (at_map x))" using at_map_Sup_pres comp_eq_elim by blast lemma at_map_Inf_pres: "at_map (\X) = Abs_atoms (Collect atom \ (\x \ X. (Rep_atoms (at_map (x::'a::complete_boolean_algebra_alt)))))" unfolding at_map_def comp_def by (metis (no_types, lifting) Abs_atoms_inverse Sup.SUP_cong atom_map_Inf_pres rangeI) lemma at_map_Inf_pres_var: "at_map \ Inf = Inf \ (`) (at_map::'a::complete_boolean_algebra_alt \ 'a atoms)" unfolding fun_eq_iff comp_def by (metis Inf_atoms.abs_eq at_map_Inf_pres image_image) text \Finally, on complete atomic boolean algebras (CABAs), at-map is an isomorphism, that is, a bijection that preserves the complete boolean algebra operations. Thus every CABA is isomorphic to a powerset boolean algebra and every powerset boolean algebra is a CABA. The bijective pair is given by at-map and Sup (defined on the powerset algebra). This theorem is a little version of Stone's theorem. In the general case, ultrafilters play the role of atoms.\ lemma "Sup \ atom_map = (id::'a::complete_atomic_boolean_algebra \ 'a)" unfolding fun_eq_iff comp_def id_def by (metis Union_upper atom_map_atoms inj_atom_map inj_def rangeI surj_atom_map) lemma inj_at_map_var: "Sup \ Rep_atoms \ at_map = (id ::'a::complete_atomic_boolean_algebra \ 'a)" unfolding at_map_def comp_def fun_eq_iff id_def by (metis Abs_atoms_inverse Union_upper atom_map_atoms inj_atom_map inj_def rangeI surj_atom_map) lemma bij_at_map: "bij (at_map::'a::complete_atomic_boolean_algebra \ 'a atoms)" unfolding bij_def by (simp add: inj_at_map surj_at_map) instance atoms :: (complete_atomic_boolean_algebra) complete_atomic_boolean_algebra.. text \A full consideration of Stone duality is left for future work.\ (* Failed attempt to prove Tarski's fixpoint theorem: The problem is that we want to use mono, but this has two type parameters. It doesn't work inside of the one-type-parameter typedef. Yet isotonicity is needed to prove inhabitance of the type. I could develop a theory of isotone endos and prove the existence of lfps and gfps, duplicating the more general facts for mono. But that's not the point. Because of this I see no direct way of proving Tarski's fixpoint theorem. Any way out? class complete_lattice_with_iso = complete_lattice + fixes f :: "'a \ 'a" (* assumes isof: "x \ y \ f x \ f y"*) typedef (overloaded) 'a Fix = "Fix (f::'a::complete_lattice_with_iso \ 'a)" setup_lifting type_definition_Fix *) end