Skip to content

Commit 89a00da

Browse files
Feat: Add some operations and lemmas on closure operators/order homs (#10348)
This adds conjugation of order homomorphisms & closure operators by order isos, as well as two new extensionality lemmas for closure operators, a proof that the inf of a closed family is closed, and that the closure of an element is the GLB of all closed elements larger than it. There is also includes some minor refactoring, moving `Set.image_sSup` from `Mathlib/Order/Hom/CompleteLattice` to `Mathlib/Data/Set/Lattice` and adding some common lemmas for `EquivLike`-things to `OrderIso`.
1 parent 1c006b3 commit 89a00da

File tree

5 files changed

+103
-11
lines changed

5 files changed

+103
-11
lines changed

Mathlib/Data/Set/Lattice.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,6 +1734,15 @@ theorem preimage_iUnion₂ {f : α → β} {s : ∀ i, κ i → Set β} :
17341734
(f ⁻¹' ⋃ (i) (j), s i j) = ⋃ (i) (j), f ⁻¹' s i j := by simp_rw [preimage_iUnion]
17351735
#align set.preimage_Union₂ Set.preimage_iUnion₂
17361736

1737+
theorem image_sUnion {f : α → β} {s : Set (Set α)} : (f '' ⋃₀ s) = ⋃₀ (image f '' s) := by
1738+
ext b
1739+
simp only [mem_image, mem_sUnion, exists_prop, sUnion_image, mem_iUnion]
1740+
constructor
1741+
· rintro ⟨a, ⟨t, ht₁, ht₂⟩, rfl⟩
1742+
exact ⟨t, ht₁, a, ht₂, rfl⟩
1743+
· rintro ⟨t, ht₁, a, ht₂, rfl⟩
1744+
exact ⟨a, ⟨t, ht₁, ht₂⟩, rfl⟩
1745+
17371746
@[simp]
17381747
theorem preimage_sUnion {f : α → β} {s : Set (Set β)} : f ⁻¹' ⋃₀s = ⋃ t ∈ s, f ⁻¹' t := by
17391748
rw [sUnion_eq_biUnion, preimage_iUnion₂]

Mathlib/Order/Closure.lean

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,28 @@ instance [Preorder α] : OrderHomClass (ClosureOperator α) α α where
8080

8181
initialize_simps_projections ClosureOperator (toFun → apply, IsClosed → isClosed)
8282

83+
84+
/-- If `c` is a closure operator on `α` and `e` an order-isomorphism
85+
between `α` and `β` then `e ∘ c ∘ e⁻¹` is a closure operator on `β`. -/
86+
@[simps apply]
87+
def conjBy {α β} [Preorder α] [Preorder β] (c : ClosureOperator α)
88+
(e : α ≃o β) : ClosureOperator β where
89+
toFun := e.conj c
90+
IsClosed b := c.IsClosed (e.symm b)
91+
monotone' _ _ h :=
92+
(map_le_map_iff e).mpr <| c.monotone <| (map_le_map_iff e.symm).mpr h
93+
le_closure' _ := e.symm_apply_le.mp (c.le_closure' _)
94+
idempotent' _ :=
95+
congrArg e <| Eq.trans (congrArg c (e.symm_apply_apply _)) (c.idempotent' _)
96+
isClosed_iff := Iff.trans c.isClosed_iff e.eq_symm_apply
97+
98+
lemma conjBy_refl {α} [Preorder α] (c : ClosureOperator α) :
99+
c.conjBy (OrderIso.refl α) = c := rfl
100+
101+
lemma conjBy_trans {α β γ} [Preorder α] [Preorder β] [Preorder γ]
102+
(e₁ : α ≃o β) (e₂ : β ≃o γ) (c : ClosureOperator α) :
103+
c.conjBy (e₁.trans e₂) = (c.conjBy e₁).conjBy e₂ := rfl
104+
83105
section PartialOrder
84106

85107
variable [PartialOrder α]
@@ -102,9 +124,8 @@ instance : Inhabited (ClosureOperator α) :=
102124
variable {α} [PartialOrder α] (c : ClosureOperator α)
103125

104126
@[ext]
105-
theorem ext : ∀ c₁ c₂ : ClosureOperator α, (c₁ : α → α) = (c₂ : α → α) → c₁ = c₂ :=
106-
DFunLike.coe_injective
107-
#align closure_operator.ext ClosureOperator.ext
127+
theorem ext : ∀ c₁ c₂ : ClosureOperator α, (∀ x, c₁ x = c₂ x) → c₁ = c₂ :=
128+
DFunLike.ext
108129

109130
/-- Constructor for a closure operator using the weaker idempotency axiom: `f (f x) ≤ f x`. -/
110131
@[simps]
@@ -195,6 +216,15 @@ theorem IsClosed.closure_le_iff (hy : c.IsClosed y) : c x ≤ y ↔ x ≤ y := b
195216

196217
lemma closure_min (hxy : x ≤ y) (hy : c.IsClosed y) : c x ≤ y := hy.closure_le_iff.2 hxy
197218

219+
lemma closure_isGLB (x : α) : IsGLB { y | x ≤ y ∧ c.IsClosed y } (c x) where
220+
left _ := and_imp.mpr closure_min
221+
right _ h := h ⟨c.le_closure x, c.isClosed_closure x⟩
222+
223+
theorem ext_isClosed (c₁ c₂ : ClosureOperator α)
224+
(h : ∀ x, c₁.IsClosed x ↔ c₂.IsClosed x) : c₁ = c₂ :=
225+
ext c₁ c₂ <| fun x => IsGLB.unique (c₁.closure_isGLB x) <|
226+
(Set.ext (and_congr_right' <| h ·)).substr (c₂.closure_isGLB x)
227+
198228
/-- A closure operator is equal to the closure operator obtained by feeding `c.closed` into the
199229
`ofPred` constructor. -/
200230
theorem eq_ofPred_closed (c : ClosureOperator α) :
@@ -262,6 +292,11 @@ def ofCompletePred (p : α → Prop) (hsinf : ∀ s, (∀ a ∈ s, p a) → p (s
262292
(fun a ↦ hsinf _ <| forall_mem_range.2 fun b ↦ b.2.2)
263293
(fun a b hab hb ↦ iInf_le_of_le ⟨b, hab, hb⟩ le_rfl)
264294

295+
theorem sInf_isClosed {c : ClosureOperator α} {S : Set α}
296+
(H : ∀ x ∈ S, c.IsClosed x) : c.IsClosed (sInf S) :=
297+
isClosed_iff_closure_le.mpr <| le_of_le_of_eq c.monotone.map_sInf_le <|
298+
Eq.trans (biInf_congr (c.isClosed_iff.mp <| H · ·)) sInf_eq_iInf.symm
299+
265300
@[simp]
266301
theorem closure_iSup_closure (f : ι → α) : c (⨆ i, c (f i)) = c (⨆ i, f i) :=
267302
le_antisymm (le_closure_iff.1 <| iSup_le fun i => c.monotone <| le_iSup f i) <|
@@ -279,6 +314,18 @@ end CompleteLattice
279314

280315
end ClosureOperator
281316

317+
/-- Conjugating `ClosureOperators` on `α` and on `β` by a fixed isomorphism
318+
`e : α ≃o β` gives an equivalence `ClosureOperator α ≃ ClosureOperator β`. -/
319+
@[simps apply symm_apply]
320+
def OrderIso.equivClosureOperator {α β} [Preorder α] [Preorder β] (e : α ≃o β) :
321+
ClosureOperator α ≃ ClosureOperator β where
322+
toFun c := c.conjBy e
323+
invFun c := c.conjBy e.symm
324+
left_inv c := Eq.trans (c.conjBy_trans _ _).symm
325+
<| Eq.trans (congrArg _ e.self_trans_symm) c.conjBy_refl
326+
right_inv c := Eq.trans (c.conjBy_trans _ _).symm
327+
<| Eq.trans (congrArg _ e.symm_trans_self) c.conjBy_refl
328+
282329
/-! ### Lower adjoint -/
283330

284331

Mathlib/Order/Hom/Basic.lean

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,40 @@ theorem symm_trans (e₁ : α ≃o β) (e₂ : β ≃o γ) : (e₁.trans e₂).s
935935
rfl
936936
#align order_iso.symm_trans OrderIso.symm_trans
937937

938+
@[simp]
939+
theorem self_trans_symm (e : α ≃o β) : e.trans e.symm = OrderIso.refl α :=
940+
RelIso.self_trans_symm e
941+
942+
@[simp]
943+
theorem symm_trans_self (e : α ≃o β) : e.symm.trans e = OrderIso.refl β :=
944+
RelIso.symm_trans_self e
945+
946+
/-- An order isomorphism between the domains and codomains of two prosets of
947+
order homomorphisms gives an order isomorphism between the two function prosets. -/
948+
@[simps apply symm_apply]
949+
def arrowCongr {α β γ δ} [Preorder α] [Preorder β] [Preorder γ] [Preorder δ]
950+
(f : α ≃o γ) (g : β ≃o δ) : (α →o β) ≃o (γ →o δ) where
951+
toFun p := .comp g <| .comp p f.symm
952+
invFun p := .comp g.symm <| .comp p f
953+
left_inv p := DFunLike.coe_injective <| by
954+
change (g.symm ∘ g) ∘ p ∘ (f.symm ∘ f) = p
955+
simp only [← DFunLike.coe_eq_coe_fn, ← OrderIso.coe_trans, Function.id_comp,
956+
OrderIso.self_trans_symm, OrderIso.coe_refl, Function.comp_id]
957+
right_inv p := DFunLike.coe_injective <| by
958+
change (g ∘ g.symm) ∘ p ∘ (f ∘ f.symm) = p
959+
simp only [← DFunLike.coe_eq_coe_fn, ← OrderIso.coe_trans, Function.id_comp,
960+
OrderIso.symm_trans_self, OrderIso.coe_refl, Function.comp_id]
961+
map_rel_iff' {p q} := by
962+
simp only [Equiv.coe_fn_mk, OrderHom.le_def, OrderHom.comp_coe,
963+
OrderHomClass.coe_coe, Function.comp_apply, map_le_map_iff]
964+
exact Iff.symm f.forall_congr_left'
965+
966+
/-- If `α` and `β` are order-isomorphic then the two orders of order-homomorphisms
967+
from `α` and `β` to themselves are order-isomorphic. -/
968+
@[simps! apply symm_apply]
969+
def conj {α β} [Preorder α] [Preorder β] (f : α ≃o β) : (α →o α) ≃ (β →o β) :=
970+
arrowCongr f f
971+
938972
/-- `Prod.swap` as an `OrderIso`. -/
939973
def prodComm : α × β ≃o β × α where
940974
toEquiv := Equiv.prodComm α β

Mathlib/Order/Hom/CompleteLattice.lean

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -946,14 +946,8 @@ theorem setPreimage_comp (g : β → γ) (f : α → β) :
946946

947947
end CompleteLatticeHom
948948

949-
theorem Set.image_sSup {f : α → β} (s : Set (Set α)) : f '' sSup s = sSup (image f '' s) := by
950-
ext b
951-
simp only [sSup_eq_sUnion, mem_image, mem_sUnion, exists_prop, sUnion_image, mem_iUnion]
952-
constructor
953-
· rintro ⟨a, ⟨t, ht₁, ht₂⟩, rfl⟩
954-
exact ⟨t, ht₁, a, ht₂, rfl⟩
955-
· rintro ⟨t, ht₁, a, ht₂, rfl⟩
956-
exact ⟨a, ⟨t, ht₁, ht₂⟩, rfl⟩
949+
theorem Set.image_sSup {f : α → β} (s : Set (Set α)) : f '' sSup s = sSup (image f '' s) :=
950+
Set.image_sUnion
957951
#align set.image_Sup Set.image_sSup
958952

959953
/-- Using `Set.image`, a function between types yields a `sSupHom` between their lattices of

Mathlib/Order/RelIso/Basic.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,14 @@ theorem symm_apply_rel (e : r ≃r s) {x y} : r (e.symm x) y ↔ s x (e y) := by
798798
rw [← e.map_rel_iff, e.apply_symm_apply]
799799
#align rel_iso.symm_apply_rel RelIso.symm_apply_rel
800800

801+
@[simp]
802+
theorem self_trans_symm (e : r ≃r s) : e.trans e.symm = RelIso.refl r :=
803+
ext e.symm_apply_apply
804+
805+
@[simp]
806+
theorem symm_trans_self (e : r ≃r s) : e.symm.trans e = RelIso.refl s :=
807+
ext e.apply_symm_apply
808+
801809
protected theorem bijective (e : r ≃r s) : Bijective e :=
802810
e.toEquiv.bijective
803811
#align rel_iso.bijective RelIso.bijective

0 commit comments

Comments
 (0)