Theory Negative_Association_More_Lattices
section ‹Preliminary Results on Lattices›
text ‹This entry establishes a few missing lemmas for the set-based theory of lattices from
``HOL-Algebra''. In particular, it introduces the sublocale for distributive lattices.
More crucially, a transfer theorem which can be used in conjunction with the Types-To-Sets mechanism
to be able to work with locally defined finite distributive lattices.
This is being needed for the verification of the negative association of permutation distributions
in Section~\ref{sec:permutation_distributions}.›
theory Negative_Association_More_Lattices
imports "HOL-Algebra.Lattice"
begin
text ‹Lemma 1 Birkhoff Lattice Theory, p.8, L3›
lemma (in lattice) meet_assoc_law:
assumes "x ∈ carrier L" "y ∈ carrier L" "z ∈ carrier L"
shows "x ⊓ (y ⊓ z) = (x ⊓ y) ⊓ z"
using assms by (metis (full_types) eq_is_equal weak_meet_assoc)
text ‹Lemma 1 Birkhoff Lattice Theory, p.8, L3›
lemma (in lattice) join_assoc_law:
assumes "x ∈ carrier L" "y ∈ carrier L" "z ∈ carrier L"
shows "x ⊔ (y ⊔ z) = (x ⊔ y) ⊔ z"
using assms by (metis (full_types) eq_is_equal weak_join_assoc)
text ‹Lemma 1 Birkhoff Lattice Theory, p.8, L4›
lemma (in lattice) absorbtion_law:
assumes "x ∈ carrier L" "y ∈ carrier L"
shows "x ⊓ (x ⊔ y) = x" "x ⊔ (x ⊓ y) = x"
proof -
have " x ⊑ x ⊔ y" using assms join_left by auto
hence "x = x ⊓ (x ⊔ y)" using assms by (intro iffD1[OF le_iff_join]) auto
thus "x ⊓ (x ⊔ y) = x" by simp
have "x ⊓ y ⊑ x" using assms meet_left by auto
hence "(x ⊓ y) ⊔ x = x" using assms le_iff_meet by (intro iffD1[OF le_iff_meet]) auto
thus "x ⊔ (x ⊓ y) = x" using join_comm by metis
qed
text ‹Theorem 9 Birkhoff Lattice Theory, p.11›
lemma (in lattice) distrib_laws_equiv:
defines "meet_distrib ≡ (∀x y z. {x,y,z}⊆carrier L ⟶ (x ⊓ (y ⊔ z)) = (x ⊓ y) ⊔ (x ⊓ z))"
defines "join_distrib ≡ (∀x y z. {x,y,z}⊆carrier L ⟶ (x ⊔ (y ⊓ z)) = (x ⊔ y) ⊓ (x ⊔ z))"
shows "meet_distrib ⟷ join_distrib"
proof
assume a:"meet_distrib"
have "(x ⊔ y) ⊓ (x ⊔ z)= x ⊔ (y ⊓ z)" (is "?L = ?R") if "{x,y,z} ⊆ carrier L" for x y z
proof -
have "?L = ((x ⊔ y) ⊓ x) ⊔ ((x ⊔ y) ⊓ z)" using a that unfolding meet_distrib_def by simp
also have "… = x ⊔ (z ⊓ (x ⊔ y))" using that absorbtion_law meet_comm by (metis insert_subset)
also have "… = x ⊔ ((z ⊓ x) ⊔ (z ⊓ y))" using a that unfolding meet_distrib_def by simp
also have "… = (x ⊔ (z ⊓ x)) ⊔ (z ⊓ y)" using that meet_assoc_law join_assoc_law by simp
also have "… = x ⊔ (z ⊓ y)" using that absorbtion_law meet_comm by (metis insert_subset)
also have "… = ?R" by (metis meet_comm)
finally show ?thesis by simp
qed
thus "join_distrib" unfolding join_distrib_def by auto
next
assume a:"join_distrib"
have "(x ⊓ y) ⊔ (x ⊓ z)= x ⊓ (y ⊔ z)" (is "?L = ?R") if "{x,y,z} ⊆ carrier L" for x y z
proof -
have "?L = ((x ⊓ y) ⊔ x) ⊓ ((x ⊓ y) ⊔ z)" using a that unfolding join_distrib_def by simp
also have "… = x ⊓ (z ⊔ (x ⊓ y))" using that absorbtion_law join_comm by (metis insert_subset)
also have "… = x ⊓ ((z ⊔ x) ⊓ (z ⊔ y))" using a that unfolding join_distrib_def by simp
also have "… = (x ⊓ (z ⊔ x)) ⊓ (z ⊔ y)" using that meet_assoc_law join_assoc_law by simp
also have "… = x ⊓ (z ⊔ y)" using that absorbtion_law join_comm by (metis insert_subset)
also have "… = ?R" by (metis join_comm)
finally show ?thesis by simp
qed
thus "meet_distrib" unfolding meet_distrib_def by auto
qed
lemma (in lattice) lub_unique_set:
assumes "is_lub L z S"
shows "z = ⨆S"
proof -
have a:"is_lub L z' S ⟹ z = z'" for z'
using least_unique assms by simp
show ?thesis
unfolding sup_def
by (rule someI2[where a="z"], rule assms(1), rule a)
qed
lemma (in lattice) lub_unique:
assumes "is_lub L z {x,y}"
shows "z = x ⊔ y"
using lub_unique_set[OF assms] unfolding join_def by auto
lemma (in lattice) glb_unique_set:
assumes "is_glb L z S"
shows "z = ⨅S"
proof -
have a:"is_glb L z' S ⟹ z = z'" for z'
using greatest_unique assms(1) by simp
show ?thesis
unfolding meet_def inf_def
by (rule someI2[where a="z"], rule assms(1), rule a)
qed
lemma (in lattice) glb_unique:
assumes "is_glb L z {x,y}"
shows "z = x ⊓ y"
using glb_unique_set[OF assms] unfolding meet_def by auto
lemma (in lattice) inf_lower:
assumes "S ⊆ carrier L" "s ∈ S" "finite S"
shows "⨅S ⊑ s"
proof -
have "is_glb L (⨅S) S" using assms(2) by (intro finite_inf_greatest assms(1,3)) auto
hence "(⨅S) ∈ Lower L S" using greatest_mem by metis
thus ?thesis using assms(1,2) by auto
qed
lemma (in lattice) sup_upper:
assumes "S ⊆ carrier L" "s ∈ S" "finite S"
shows "s ⊑ ⨆S"
proof -
have "is_lub L (⨆S) S" using assms(2) by (intro finite_sup_least assms(1,3)) auto
hence "(⨆S) ∈ Upper L S" using least_mem by metis
thus ?thesis using assms(1,2) by auto
qed
locale distrib_lattice = lattice +
assumes max_distrib:
"x ∈ carrier L ⟹ y ∈ carrier L ⟹ z ∈ carrier L ⟹ (x ⊓ (y ⊔ z)) = (x ⊓ y) ⊔ (x ⊓ z)"
begin
lemma min_distrib:
assumes "x ∈ carrier L" "y ∈ carrier L" "z ∈ carrier L"
shows "(x ⊔ (y ⊓ z)) = (x ⊔ y) ⊓ (x ⊔ z)"
proof -
have a:"∀x y z. {x, y, z} ⊆ carrier L ⟶ x ⊓ (y ⊔ z) = x ⊓ y ⊔ x ⊓ z" using max_distrib by auto
show ?thesis using iffD1[OF distrib_laws_equiv a] assms by simp
qed
end
locale finite_ne_distrib_lattice = distrib_lattice +
assumes non_empty_carrier: "carrier L ≠ {}"
assumes finite_carrier: "finite (carrier L)"
begin
lemma bounded_lattice_axioms_1: "∃x. least L x (carrier L)"
proof -
have "⨅carrier L ∈ Lower L (carrier L)"
by (intro greatest_mem[where L="L"] finite_inf_greatest[OF finite_carrier _ non_empty_carrier])
auto
hence "∀x ∈ carrier L. (⨅carrier L)⊑x" unfolding Lower_def by auto
moreover have "⨅carrier L ∈ carrier L"
using finite_inf_closed[OF finite_carrier _ non_empty_carrier] by auto
ultimately have "least L (⨅carrier L) (carrier L)"
unfolding least_def by auto
thus ?thesis by auto
qed
lemma bounded_lattice_axioms_2: "∃x. greatest L x (carrier L)"
proof -
have "⨆carrier L ∈ Upper L (carrier L)"
by (intro least_mem[where L="L"] finite_sup_least[OF finite_carrier _ non_empty_carrier])
auto
hence "∀x ∈ carrier L. x ⊑ (⨆carrier L)" unfolding Upper_def by auto
moreover have "⨆carrier L ∈ carrier L"
using finite_sup_closed[OF finite_carrier _ non_empty_carrier] by auto
ultimately have "greatest L (⨆carrier L) (carrier L)"
unfolding greatest_def by auto
thus ?thesis by auto
qed
sublocale bounded_lattice
using bounded_lattice_axioms_1 bounded_lattice_axioms_2
by (unfold_locales) auto
lemma inf_empty: "⨅ {} = ⊤"
proof -
have "is_glb L ⊤ {}" using top_greatest by simp
thus ?thesis using glb_unique_set by auto
qed
lemma inf_closed: "S ⊆ carrier L ⟹⨅S ∈ carrier L"
using finite_carrier inf_empty top_closed finite_inf_closed
by (metis finite_subset)
lemma inf_insert:
assumes "x ∈ carrier L" "S ⊆ carrier L"
shows "⨅ (insert x S) = x ⊓ (⨅S)"
proof -
have fin_S: "finite S" using finite_carrier assms(2) finite_subset by metis
have inf_S_carr: "⨅S ∈ carrier L" using inf_closed[OF assms(2)] by force
have "x ⊓ (⨅S) ⊑ s" if "s ∈ S" for s
proof -
have "⨅S ⊑ s" using that fin_S assms(2)
by (metis empty_iff finite_inf_greatest greatest_Lower_below)
moreover have "x ⊓ (⨅S) ⊑ ⨅S" using inf_S_carr assms(1) meet_right by metis
ultimately show ?thesis using inf_S_carr meet_closed
by (meson assms le_trans subsetD that)
qed
moreover have "x ⊓ (⨅S) ⊑ x" using inf_S_carr assms(1) meet_left by metis
ultimately have "x ⊓ (⨅S) ∈ Lower L (insert x S)"
using assms(1) meet_closed inf_S_carr unfolding Lower_def by auto
moreover have "y ⊑ (x ⊓ (⨅S))" if "y ∈ Lower L (insert x S)" for y
proof-
have y_carr: "y ∈ carrier L" using that assms unfolding Lower_def by auto
have y_lb: "y ⊑ x" using that assms unfolding Lower_def by auto
moreover have "y ∈ Lower L S" using that unfolding Lower_def by auto
hence "y ⊑ ⨅S" using finite_inf_greatest[OF fin_S assms(2)]
by (metis greatest_le inf_empty top_higher y_carr)
ultimately show ?thesis
using y_carr inf_S_carr assms(1) meet_le by simp
qed
ultimately have "is_glb L (x ⊓ (⨅S)) (insert x S)" by (simp add: greatest_def)
thus ?thesis by (intro glb_unique_set[symmetric])
qed
lemma sup_empty: "⨆ {} = ⊥"
proof -
have "is_lub L ⊥ {}" using bottom_least by simp
thus ?thesis using lub_unique_set by auto
qed
lemma sup_closed: "S ⊆ carrier L ⟹⨆ S ∈ carrier L"
using finite_carrier sup_empty bottom_closed finite_sup_closed
by (metis finite_subset)
lemma sup_insert:
assumes "x ∈ carrier L" "S ⊆ carrier L"
shows "⨆ (insert x S) = x ⊔ (⨆S)"
proof -
have fin_S: "finite S" using finite_carrier assms(2) finite_subset by metis
have sup_S_carr: "⨆S ∈ carrier L" using sup_closed[OF assms(2)] by force
have "s ⊑ x ⊔ (⨆S)" if "s ∈ S" for s
proof -
have "s ⊑ ⨆S" using that fin_S assms(2)
by (metis empty_iff finite_sup_least least_Upper_above)
moreover have " ⨆S ⊑ x ⊔ (⨆S) " using sup_S_carr assms(1) join_right by metis
ultimately show ?thesis using sup_S_carr join_closed assms
by (meson le_trans subsetD that)
qed
moreover have "x ⊑ x ⊔ (⨆S)" using sup_S_carr assms(1) join_left by metis
ultimately have "x ⊔ (⨆S) ∈ Upper L (insert x S)"
using assms(1) sup_S_carr unfolding Upper_def by auto
moreover have "x ⊔ (⨆S) ⊑ y" if "y ∈ Upper L (insert x S)" for y
proof-
have y_carr: "y ∈ carrier L" using that assms unfolding Lower_def by auto
have y_lb: "x ⊑ y" using that assms by auto
moreover have "y ∈ Upper L S" using that unfolding Upper_def by auto
hence "⨆S ⊑ y" using finite_sup_least[OF fin_S assms(2)]
using least_le sup_empty bottom_lower y_carr by metis
ultimately show ?thesis
using y_carr sup_S_carr assms(1) join_le by simp
qed
ultimately have "is_lub L (x ⊔ (⨆S)) (insert x S)" by (simp add: least_def)
thus ?thesis by (intro lub_unique_set[symmetric])
qed
lemma inf_carrier: "⨅ (carrier L) = ⊥"
proof -
have "⨅carrier L ∈ Lower L (carrier L)"
by (intro greatest_mem[where L="L"] finite_inf_greatest[OF finite_carrier _ non_empty_carrier])
auto
hence "∀x ∈ carrier L. (⨅carrier L)⊑x" unfolding Lower_def by auto
moreover have "⨅carrier L ∈ carrier L"
using finite_inf_closed[OF finite_carrier _ non_empty_carrier] by auto
ultimately show ?thesis by (intro bottom_eq) auto
qed
lemma sup_carrier: "⨆ (carrier L) = ⊤"
proof -
have "⨆carrier L ∈ Upper L (carrier L)"
by (intro least_mem[where L="L"] finite_sup_least[OF finite_carrier _ non_empty_carrier])
auto
hence "∀x ∈ carrier L. x⊑ (⨆carrier L)" unfolding Upper_def by auto
moreover have "⨆carrier L ∈ carrier L"
using finite_sup_closed[OF finite_carrier _ non_empty_carrier] by auto
ultimately show ?thesis by (intro top_eq) auto
qed
lemma transfer_to_type:
assumes "finite (carrier L)" "type_definition Rep Abs (carrier L)"
defines "inf' ≡ (λM. Abs (⨅ Rep ` M))"
defines "sup' ≡ (λM. Abs (⨆ Rep ` M))"
defines "join' ≡ (λx y. Abs (Rep x ⊓ Rep y))"
defines "le' ≡ (λx y. (Rep x ⊑ Rep y))"
defines "less' ≡ (λx y. (Rep x ⊏ Rep y))"
defines "meet' ≡ (λx y. (Abs (Rep x ⊔ Rep y)))"
defines "bot'≡ (Abs ⊥ :: 'c)"
defines "top' ≡ Abs ⊤"
shows "class.finite_distrib_lattice inf' sup' join' le' less' meet' bot' top'"
proof -
interpret type_definition Rep Abs "(carrier L)"
using assms(2) by auto
note defs = inf'_def sup'_def join'_def le'_def less'_def meet'_def bot'_def bot'_def top'_def
note td = Rep Rep_inverse Abs_inverse inf_closed sup_closed meet_closed join_closed Rep_range
have class_lattice: "class.lattice join' le' less' meet'"
unfolding defs using td
proof (unfold_locales, goal_cases)
case 1 thus ?case unfolding lless_eq by auto
next
case 2 thus ?case by (metis le_refl)
next
case 3 thus ?case by (metis le_trans)
next
case 4 thus ?case by (meson Rep_inject local.le_antisym)
next
case 5 thus ?case by (metis meet_left)
next
case 6 thus ?case by (metis meet_right)
next
case 7 thus ?case by (metis meet_le)
next
case 8 thus ?case by (metis join_left)
next
case 9 thus ?case by (metis join_right)
next
case 10 thus ?case by (metis join_le)
qed
have class_distrib_lattice: "class.distrib_lattice join' le' less' meet'"
unfolding class.distrib_lattice_def eqTrueI[OF class_lattice]
unfolding defs class.distrib_lattice_axioms_def using td
using min_distrib by auto
have class_finite: "class.finite TYPE('c)"
by (unfold_locales) (metis assms(1) Abs_image finite_imageI)
have class_finite_lattice: "class.finite_lattice inf' sup' join' le' less' meet' bot' top'"
unfolding class.finite_lattice_def eqTrueI[OF class_lattice] eqTrueI[OF class_finite]
unfolding defs class.distrib_lattice_axioms_def class.finite_lattice_axioms_def using td
proof (intro conjI TrueI, goal_cases)
case 1 thus ?case using sup_carrier inf_empty by simp
next
case 2 thus ?case unfolding image_insert by (metis inf_insert image_subsetI)
next
case 3 thus ?case using inf_carrier sup_empty by simp
next
case 4 thus ?case unfolding image_insert by (metis sup_insert image_subsetI)
next
case 5 thus ?case using inf_carrier by simp
next
case 6 thus ?case using sup_carrier by simp
qed
show ?thesis
using class_finite_lattice class_distrib_lattice
unfolding class.finite_distrib_lattice_def by auto
qed
end
end