Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 0104948

Browse files
awainversejcommelin
andcommitted
feat(order/atoms): further facts about atoms, coatoms, and simple lattices (#5493)
Provides possible instances of `bounded_distrib_lattice`, `boolean_algebra`, `complete_lattice`, and `complete_boolean_algebra` on a simple lattice Relates the `is_atom` and `is_coatom` conditions to `is_simple_lattice` structures on intervals Shows that all three conditions are preserved by `order_iso`s Adds more instances on `bool`, including `is_simple_lattice` Co-authored-by: Johan Commelin <johan@commelin.net> Co-authored-by: Aaron Anderson <65780815+awainverse@users.noreply.github.com>
1 parent bc94d05 commit 0104948

File tree

5 files changed

+229
-26
lines changed

5 files changed

+229
-26
lines changed

src/data/bool.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,12 @@ instance : linear_order bool :=
160160

161161
namespace bool
162162

163+
@[simp] lemma ff_le {x : bool} : ff ≤ x := or.intro_left _ rfl
164+
165+
@[simp] lemma le_tt {x : bool} : x ≤ tt := or.intro_right _ rfl
166+
167+
@[simp] lemma ff_lt_tt : ff < tt := lt_of_le_of_ne ff_le ff_ne_tt
168+
163169
/-- convert a `bool` to a `ℕ`, `false -> 0`, `true -> 1` -/
164170
def to_nat (b : bool) : ℕ :=
165171
cond b 1 0

src/logic/nontrivial.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,3 +261,9 @@ add_tactic_doc
261261
tags := ["logic", "type class"] }
262262

263263
end tactic.interactive
264+
265+
namespace bool
266+
267+
instance : nontrivial bool := ⟨⟨tt,ff, tt_eq_ff_eq_false⟩⟩
268+
269+
end bool

src/order/atoms.lean

Lines changed: 170 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Author: Aaron Anderson.
55
-/
66

7-
import order.bounded_lattice
7+
import order.complete_boolean_algebra
88
import order.order_dual
9+
import order.lattice_intervals
10+
import order.rel_iso
11+
import data.fintype.basic
912

1013
/-!
1114
# Atoms, Coatoms, and Simple Lattices
@@ -14,9 +17,25 @@ This module defines atoms, which are minimal non-`⊥` elements in bounded latti
1417
which are lattices with only two elements, and related ideas.
1518
1619
## Main definitions
20+
21+
### Atoms and Coatoms
1722
* `is_atom a` indicates that the only element below `a` is `⊥`.
1823
* `is_coatom a` indicates that the only element above `a` is `⊤`.
24+
25+
### Simple Lattices
1926
* `is_simple_lattice` indicates that a bounded lattice has only two elements, `⊥` and `⊤`.
27+
* `is_simple_lattice.bounded_distrib_lattice`
28+
* Given an instance of `is_simple_lattice`, we provide the following definitions. These are not
29+
made global instances as they contain data :
30+
* `is_simple_lattice.boolean_algebra`
31+
* `is_simple_lattice.complete_lattice`
32+
* `is_simple_lattice.complete_boolean_algebra`
33+
34+
## Main results
35+
* `is_atom_iff_is_coatom_dual` and `is_coatom_iff_is_atom_dual` express the (definitional) duality
36+
of `is_atom` and `is_coatom`.
37+
* `is_simple_lattice_iff_is_atom_top` and `is_simple_lattice_iff_is_coatom_bot` express the
38+
connection between atoms, coatoms, and simple lattices
2039
2140
-/
2241

@@ -108,6 +127,113 @@ is_simple_lattice_iff_is_simple_lattice_order_dual.1 (by apply_instance)
108127

109128
end is_simple_lattice
110129

130+
namespace is_simple_lattice
131+
132+
variables [bounded_lattice α] [is_simple_lattice α]
133+
134+
/-- A simple `bounded_lattice` is also distributive. -/
135+
@[priority 100]
136+
instance : bounded_distrib_lattice α :=
137+
{ le_sup_inf := λ x y z, by { rcases eq_bot_or_eq_top x with rfl | rfl; simp },
138+
.. (infer_instance : bounded_lattice α) }
139+
140+
section decidable_eq
141+
variable [decidable_eq α]
142+
143+
/-- Every simple lattice is order-isomorphic to `bool`. -/
144+
def order_iso_bool : α ≃o bool :=
145+
{ to_fun := λ x, x = ⊤,
146+
inv_fun := λ x, cond x ⊤ ⊥,
147+
left_inv := λ x, by { rcases (eq_bot_or_eq_top x) with rfl | rfl; simp [bot_ne_top] },
148+
right_inv := λ x, by { cases x; simp [bot_ne_top] },
149+
map_rel_iff' := λ a b, begin
150+
rcases (eq_bot_or_eq_top a) with rfl | rfl,
151+
{ simp [bot_ne_top] },
152+
{ rcases (eq_bot_or_eq_top b) with rfl | rfl,
153+
{ simp [bot_ne_top.symm, bot_ne_top, bool.ff_lt_tt] },
154+
{ simp [bot_ne_top] } }
155+
end }
156+
157+
@[priority 200]
158+
instance : fintype α := fintype.of_equiv bool (order_iso_bool.to_equiv).symm
159+
160+
/-- A simple `bounded_lattice` is also a `boolean_algebra`. -/
161+
protected def boolean_algebra : boolean_algebra α :=
162+
{ compl := λ x, if x = ⊥ thenelse ⊥,
163+
sdiff := λ x y, if x = ⊤ ∧ y = ⊥ thenelse ⊥,
164+
sdiff_eq := λ x y, by { rcases eq_bot_or_eq_top x with rfl | rfl; simp [bot_ne_top] },
165+
inf_compl_le_bot := λ x, by { rcases eq_bot_or_eq_top x with rfl | rfl; simp },
166+
top_le_sup_compl := λ x, by { rcases eq_bot_or_eq_top x with rfl | rfl; simp },
167+
.. is_simple_lattice.bounded_distrib_lattice }
168+
169+
end decidable_eq
170+
171+
open_locale classical
172+
173+
/-- A simple `bounded_lattice` is also complete. -/
174+
protected noncomputable def complete_lattice : complete_lattice α :=
175+
{ Sup := λ s, if ⊤ ∈ s thenelse ⊥,
176+
Inf := λ s, if ⊥ ∈ s thenelse ⊤,
177+
le_Sup := λ s x h, by { rcases eq_bot_or_eq_top x with rfl | rfl,
178+
{ exact bot_le },
179+
{ rw if_pos h } },
180+
Sup_le := λ s x h, by { rcases eq_bot_or_eq_top x with rfl | rfl,
181+
{ rw if_neg,
182+
intro con,
183+
exact bot_ne_top (eq_top_iff.2 (h ⊤ con)) },
184+
{ exact le_top } },
185+
Inf_le := λ s x h, by { rcases eq_bot_or_eq_top x with rfl | rfl,
186+
{ rw if_pos h },
187+
{ exact le_top } },
188+
le_Inf := λ s x h, by { rcases eq_bot_or_eq_top x with rfl | rfl,
189+
{ exact bot_le },
190+
{ rw if_neg,
191+
intro con,
192+
exact top_ne_bot (eq_bot_iff.2 (h ⊥ con)) } },
193+
.. (infer_instance : bounded_lattice α) }
194+
195+
/-- A simple `bounded_lattice` is also a `complete_boolean_algebra`. -/
196+
protected noncomputable def complete_boolean_algebra : complete_boolean_algebra α :=
197+
{ infi_sup_le_sup_Inf := λ x s, by { rcases eq_bot_or_eq_top x with rfl | rfl,
198+
{ simp only [bot_sup_eq, ← Inf_eq_infi], apply le_refl },
199+
{ simp only [top_sup_eq, le_top] }, },
200+
inf_Sup_le_supr_inf := λ x s, by { rcases eq_bot_or_eq_top x with rfl | rfl,
201+
{ simp only [bot_inf_eq, bot_le] },
202+
{ simp only [top_inf_eq, ← Sup_eq_supr], apply le_refl } },
203+
.. is_simple_lattice.complete_lattice,
204+
.. is_simple_lattice.boolean_algebra }
205+
206+
end is_simple_lattice
207+
208+
namespace fintype
209+
namespace is_simple_lattice
210+
variables [bounded_lattice α] [is_simple_lattice α] [decidable_eq α]
211+
212+
lemma univ : (finset.univ : finset α) = {⊤, ⊥} :=
213+
begin
214+
change finset.map _ (finset.univ : finset bool) = _,
215+
rw fintype.univ_bool,
216+
simp only [finset.map_insert, function.embedding.coe_fn_mk, finset.map_singleton],
217+
refl,
218+
end
219+
220+
lemma card : fintype.card α = 2 :=
221+
(fintype.of_equiv_card _).trans fintype.card_bool
222+
223+
end is_simple_lattice
224+
end fintype
225+
226+
namespace bool
227+
228+
instance : is_simple_lattice bool :=
229+
⟨λ a, begin
230+
rw [← finset.mem_singleton, or.comm, ← finset.mem_insert,
231+
top_eq_tt, bot_eq_ff, ← fintype.univ_bool],
232+
apply finset.mem_univ,
233+
end
234+
235+
end bool
236+
111237
theorem is_simple_lattice_iff_is_atom_top [bounded_lattice α] :
112238
is_simple_lattice α ↔ is_atom (⊤ : α) :=
113239
⟨λ h, @is_atom_top _ _ h, λ h, {
@@ -116,4 +242,46 @@ theorem is_simple_lattice_iff_is_atom_top [bounded_lattice α] :
116242

117243
theorem is_simple_lattice_iff_is_coatom_bot [bounded_lattice α] :
118244
is_simple_lattice α ↔ is_coatom (⊥ : α) :=
119-
iff.trans is_simple_lattice_iff_is_simple_lattice_order_dual is_simple_lattice_iff_is_atom_top
245+
is_simple_lattice_iff_is_simple_lattice_order_dual.trans is_simple_lattice_iff_is_atom_top
246+
247+
namespace set
248+
249+
theorem is_simple_lattice_Iic_iff_is_atom [bounded_lattice α] {a : α} :
250+
is_simple_lattice (Iic a) ↔ is_atom a :=
251+
is_simple_lattice_iff_is_atom_top.trans $ and_congr (not_congr subtype.mk_eq_mk)
252+
⟨λ h b ab, subtype.mk_eq_mk.1 (h ⟨b, le_of_lt ab⟩ ab),
253+
λ h ⟨b, hab⟩ hbotb, subtype.mk_eq_mk.2 (h b (subtype.mk_lt_mk.1 hbotb))⟩
254+
255+
theorem is_simple_lattice_Ici_iff_is_coatom [bounded_lattice α] {a : α} :
256+
is_simple_lattice (Ici a) ↔ is_coatom a :=
257+
is_simple_lattice_iff_is_coatom_bot.trans $ and_congr (not_congr subtype.mk_eq_mk)
258+
⟨λ h b ab, subtype.mk_eq_mk.1 (h ⟨b, le_of_lt ab⟩ ab),
259+
λ h ⟨b, hab⟩ hbotb, subtype.mk_eq_mk.2 (h b (subtype.mk_lt_mk.1 hbotb))⟩
260+
261+
end set
262+
263+
namespace order_iso
264+
265+
variables [bounded_lattice α] {β : Type*} [bounded_lattice β] (f : α ≃o β)
266+
include f
267+
268+
@[simp] lemma is_atom_iff (a : α) : is_atom (f a) ↔ is_atom a :=
269+
and_congr (not_congr ⟨λ h, f.injective (f.map_bot.symm ▸ h), λ h, f.map_bot ▸ (congr rfl h)⟩)
270+
⟨λ h b hb, f.injective ((h (f b) ((f : α ↪o β).lt_iff_lt.2 hb)).trans f.map_bot.symm),
271+
λ h b hb, f.symm.injective begin
272+
rw f.symm.map_bot,
273+
apply h,
274+
rw [← f.symm_apply_apply a],
275+
exact (f.symm : β ↪o α).lt_iff_lt.2 hb,
276+
end
277+
278+
@[simp] lemma is_coatom_iff (a : α) : is_coatom (f a) ↔ is_coatom a := f.dual.is_atom_iff a
279+
280+
lemma is_simple_lattice_iff (f : α ≃o β) : is_simple_lattice α ↔ is_simple_lattice β :=
281+
by rw [is_simple_lattice_iff_is_atom_top, is_simple_lattice_iff_is_atom_top,
282+
← f.is_atom_iff ⊤, f.map_top]
283+
284+
lemma is_simple_lattice [h : is_simple_lattice β] (f : α ≃o β) : is_simple_lattice α :=
285+
f.is_simple_lattice_iff.mpr h
286+
287+
end order_iso

src/order/bounded_lattice.lean

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -826,24 +826,6 @@ end with_top
826826

827827
namespace subtype
828828

829-
/-- A subtype forms a `⊔`-semilattice if `⊔` preserves the property. -/
830-
protected def semilattice_sup [semilattice_sup α] {P : α → Prop}
831-
(Psup : ∀⦃x y⦄, P x → P y → P (x ⊔ y)) : semilattice_sup {x : α // P x} :=
832-
{ sup := λ x y, ⟨x.1 ⊔ y.1, Psup x.2 y.2⟩,
833-
le_sup_left := λ x y, @le_sup_left _ _ (x : α) y,
834-
le_sup_right := λ x y, @le_sup_right _ _ (x : α) y,
835-
sup_le := λ x y z h1 h2, @sup_le α _ _ _ _ h1 h2,
836-
..subtype.partial_order P }
837-
838-
/-- A subtype forms a `⊓`-semilattice if `⊓` preserves the property. -/
839-
protected def semilattice_inf [semilattice_inf α] {P : α → Prop}
840-
(Pinf : ∀⦃x y⦄, P x → P y → P (x ⊓ y)) : semilattice_inf {x : α // P x} :=
841-
{ inf := λ x y, ⟨x.1 ⊓ y.1, Pinf x.2 y.2⟩,
842-
inf_le_left := λ x y, @inf_le_left _ _ (x : α) y,
843-
inf_le_right := λ x y, @inf_le_right _ _ (x : α) y,
844-
le_inf := λ x y z h1 h2, @le_inf α _ _ _ _ h1 h2,
845-
..subtype.partial_order P }
846-
847829
/-- A subtype forms a `⊔`-`⊥`-semilattice if `⊥` and `⊔` preserve the property. -/
848830
protected def semilattice_sup_bot [semilattice_sup_bot α] {P : α → Prop}
849831
(Pbot : P ⊥) (Psup : ∀⦃x y⦄, P x → P y → P (x ⊔ y)) : semilattice_sup_bot {x : α // P x} :=
@@ -865,12 +847,6 @@ protected def semilattice_inf_top [semilattice_inf_top α] {P : α → Prop}
865847
le_top := λ x, @le_top α _ x,
866848
..subtype.semilattice_inf Pinf }
867849

868-
/-- A subtype forms a lattice if `⊔` and `⊓` preserve the property. -/
869-
protected def lattice [lattice α] {P : α → Prop}
870-
(Psup : ∀⦃x y⦄, P x → P y → P (x ⊔ y)) (Pinf : ∀⦃x y⦄, P x → P y → P (x ⊓ y)) :
871-
lattice {x : α // P x} :=
872-
{ ..subtype.semilattice_inf Pinf, ..subtype.semilattice_sup Psup }
873-
874850
end subtype
875851

876852
namespace order_dual
@@ -1125,3 +1101,22 @@ lemma bot_ne_top : (⊥ : α) ≠ ⊤ :=
11251101
lemma top_ne_bot : (⊤ : α) ≠ ⊥ := ne.symm bot_ne_top
11261102

11271103
end nontrivial
1104+
1105+
namespace bool
1106+
1107+
instance : bounded_lattice bool :=
1108+
{ top := tt,
1109+
le_top := λ x, le_tt,
1110+
bot := ff,
1111+
bot_le := λ x, ff_le,
1112+
.. (infer_instance : lattice bool)}
1113+
1114+
end bool
1115+
1116+
section bool
1117+
1118+
@[simp] lemma top_eq_tt : ⊤ = tt := rfl
1119+
1120+
@[simp] lemma bot_eq_ff : ⊥ = ff := rfl
1121+
1122+
end bool

src/order/lattice.lean

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,3 +480,31 @@ instance [distrib_lattice α] [distrib_lattice β] : distrib_lattice (α × β)
480480
.. prod.lattice α β }
481481

482482
end prod
483+
484+
namespace subtype
485+
486+
/-- A subtype forms a `⊔`-semilattice if `⊔` preserves the property. -/
487+
protected def semilattice_sup [semilattice_sup α] {P : α → Prop}
488+
(Psup : ∀⦃x y⦄, P x → P y → P (x ⊔ y)) : semilattice_sup {x : α // P x} :=
489+
{ sup := λ x y, ⟨x.1 ⊔ y.1, Psup x.2 y.2⟩,
490+
le_sup_left := λ x y, @le_sup_left _ _ (x : α) y,
491+
le_sup_right := λ x y, @le_sup_right _ _ (x : α) y,
492+
sup_le := λ x y z h1 h2, @sup_le α _ _ _ _ h1 h2,
493+
..subtype.partial_order P }
494+
495+
/-- A subtype forms a `⊓`-semilattice if `⊓` preserves the property. -/
496+
protected def semilattice_inf [semilattice_inf α] {P : α → Prop}
497+
(Pinf : ∀⦃x y⦄, P x → P y → P (x ⊓ y)) : semilattice_inf {x : α // P x} :=
498+
{ inf := λ x y, ⟨x.1 ⊓ y.1, Pinf x.2 y.2⟩,
499+
inf_le_left := λ x y, @inf_le_left _ _ (x : α) y,
500+
inf_le_right := λ x y, @inf_le_right _ _ (x : α) y,
501+
le_inf := λ x y z h1 h2, @le_inf α _ _ _ _ h1 h2,
502+
..subtype.partial_order P }
503+
504+
/-- A subtype forms a lattice if `⊔` and `⊓` preserve the property. -/
505+
protected def lattice [lattice α] {P : α → Prop}
506+
(Psup : ∀⦃x y⦄, P x → P y → P (x ⊔ y)) (Pinf : ∀⦃x y⦄, P x → P y → P (x ⊓ y)) :
507+
lattice {x : α // P x} :=
508+
{ ..subtype.semilattice_inf Pinf, ..subtype.semilattice_sup Psup }
509+
510+
end subtype

0 commit comments

Comments
 (0)