Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(linear_algebra/basic): move the lattice structure to its own…
… file (#6767) The entire lattice structure is thoroughly uninteresting. By moving it to its own shorter file, it should be easier to unify with the lattice of `submonoid` I'd hope in future we can generate this automatically for any `subobject A` with an injection into `set A`.
- Loading branch information
1 parent
ce107da
commit 591c34b
Showing
2 changed files
with
183 additions
and
146 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
/- | ||
Copyright (c) 2017 Johannes Hölzl. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Johannes Hölzl, Mario Carneiro, Kevin Buzzard, Yury Kudryashov | ||
-/ | ||
import algebra.module.submodule | ||
|
||
/-! | ||
# The lattice structure on `submodule`s | ||
This file defines the lattice structure on submodules, `submodule.complete_lattice`, with `⊥` | ||
defined as `{0}` and `⊓` defined as intersection of the underlying carrier. | ||
If `p` and `q` are submodules of a module, `p ≤ q` means that `p ⊆ q`. | ||
Many results about operations on this lattice structure are defined in `linear_algebra/basic.lean`, | ||
most notably those which use `span`. | ||
## Implementation notes | ||
This structure should match the `add_submonoid.complete_lattice` structure, and we should try | ||
to unify the APIs where possible. | ||
-/ | ||
|
||
variables {R : Type*} {M : Type*} | ||
|
||
section add_comm_monoid | ||
variables [semiring R] [add_comm_monoid M] [semimodule R M] | ||
variables {p q : submodule R M} | ||
|
||
namespace submodule | ||
|
||
instance : partial_order (submodule R M) := | ||
{ le := λ p q, ∀ ⦃x⦄, x ∈ p → x ∈ q, | ||
..partial_order.lift (coe : submodule R M → set M) coe_injective } | ||
|
||
lemma le_def : p ≤ q ↔ (p : set M) ⊆ q := iff.rfl | ||
|
||
@[simp, norm_cast] lemma coe_subset_coe : (p : set M) ⊆ q ↔ p ≤ q := iff.rfl | ||
|
||
lemma le_def' : p ≤ q ↔ ∀ x ∈ p, x ∈ q := iff.rfl | ||
|
||
lemma lt_def : p < q ↔ (p : set M) ⊂ q := iff.rfl | ||
|
||
lemma not_le_iff_exists : ¬ (p ≤ q) ↔ ∃ x ∈ p, x ∉ q := set.not_subset | ||
|
||
lemma exists_of_lt {p q : submodule R M} : p < q → ∃ x ∈ q, x ∉ p := set.exists_of_ssubset | ||
|
||
lemma lt_iff_le_and_exists : p < q ↔ p ≤ q ∧ ∃ x ∈ q, x ∉ p := | ||
by rw [lt_iff_le_not_le, not_le_iff_exists] | ||
|
||
/-- The set `{0}` is the bottom element of the lattice of submodules. -/ | ||
instance : has_bot (submodule R M) := | ||
⟨{ carrier := {0}, smul_mem' := by simp { contextual := tt }, .. (⊥ : add_submonoid M)}⟩ | ||
|
||
instance inhabited' : inhabited (submodule R M) := ⟨⊥⟩ | ||
|
||
@[simp] lemma bot_coe : ((⊥ : submodule R M) : set M) = {0} := rfl | ||
@[simp] lemma bot_to_add_submonoid : (⊥ : submodule R M).to_add_submonoid = ⊥ := rfl | ||
|
||
section | ||
variables (R) | ||
@[simp] lemma mem_bot {x : M} : x ∈ (⊥ : submodule R M) ↔ x = 0 := set.mem_singleton_iff | ||
end | ||
|
||
instance unique_bot : unique (⊥ : submodule R M) := | ||
⟨infer_instance, λ x, subtype.ext $ (mem_bot R).1 x.mem⟩ | ||
|
||
lemma nonzero_mem_of_bot_lt {I : submodule R M} (bot_lt : ⊥ < I) : ∃ a : I, a ≠ 0 := | ||
begin | ||
have h := (submodule.lt_iff_le_and_exists.1 bot_lt).2, | ||
tidy, | ||
end | ||
|
||
instance : order_bot (submodule R M) := | ||
{ bot := ⊥, | ||
bot_le := λ p x, by simp {contextual := tt}, | ||
..submodule.partial_order } | ||
|
||
protected lemma eq_bot_iff (p : submodule R M) : p = ⊥ ↔ ∀ x ∈ p, x = (0 : M) := | ||
⟨ λ h, h.symm ▸ λ x hx, (mem_bot R).mp hx, | ||
λ h, eq_bot_iff.mpr (λ x hx, (mem_bot R).mpr (h x hx)) ⟩ | ||
|
||
protected lemma ne_bot_iff (p : submodule R M) : p ≠ ⊥ ↔ ∃ x ∈ p, x ≠ (0 : M) := | ||
by { haveI := classical.prop_decidable, simp_rw [ne.def, p.eq_bot_iff, not_forall] } | ||
|
||
/-- The universal set is the top element of the lattice of submodules. -/ | ||
instance : has_top (submodule R M) := | ||
⟨{ carrier := set.univ, smul_mem' := λ _ _ _, trivial, .. (⊤ : add_submonoid M)}⟩ | ||
|
||
@[simp] lemma top_coe : ((⊤ : submodule R M) : set M) = set.univ := rfl | ||
|
||
@[simp] lemma top_to_add_submonoid : (⊤ : submodule R M).to_add_submonoid = ⊤ := rfl | ||
|
||
@[simp] lemma mem_top {x : M} : x ∈ (⊤ : submodule R M) := trivial | ||
|
||
instance : order_top (submodule R M) := | ||
{ top := ⊤, | ||
le_top := λ p x _, trivial, | ||
..submodule.partial_order } | ||
|
||
lemma eq_top_iff' {p : submodule R M} : p = ⊤ ↔ ∀ x, x ∈ p := | ||
eq_top_iff.trans ⟨λ h x, h trivial, λ h x _, h x⟩ | ||
|
||
instance : has_Inf (submodule R M) := | ||
⟨λ S, { | ||
carrier := ⋂ s ∈ S, (s : set M), | ||
zero_mem' := by simp, | ||
add_mem' := by simp [add_mem] {contextual := tt}, | ||
smul_mem' := by simp [smul_mem] {contextual := tt} }⟩ | ||
|
||
private lemma Inf_le' {S : set (submodule R M)} {p} : p ∈ S → Inf S ≤ p := | ||
set.bInter_subset_of_mem | ||
|
||
private lemma le_Inf' {S : set (submodule R M)} {p} : (∀q ∈ S, p ≤ q) → p ≤ Inf S := | ||
set.subset_bInter | ||
|
||
instance : has_inf (submodule R M) := | ||
⟨λ p q, { | ||
carrier := p ∩ q, | ||
zero_mem' := by simp, | ||
add_mem' := by simp [add_mem] {contextual := tt}, | ||
smul_mem' := by simp [smul_mem] {contextual := tt} }⟩ | ||
|
||
instance : complete_lattice (submodule R M) := | ||
{ sup := λ a b, Inf {x | a ≤ x ∧ b ≤ x}, | ||
le_sup_left := λ a b, le_Inf' $ λ x ⟨ha, hb⟩, ha, | ||
le_sup_right := λ a b, le_Inf' $ λ x ⟨ha, hb⟩, hb, | ||
sup_le := λ a b c h₁ h₂, Inf_le' ⟨h₁, h₂⟩, | ||
inf := (⊓), | ||
le_inf := λ a b c, set.subset_inter, | ||
inf_le_left := λ a b, set.inter_subset_left _ _, | ||
inf_le_right := λ a b, set.inter_subset_right _ _, | ||
Sup := λtt, Inf {t | ∀t'∈tt, t' ≤ t}, | ||
le_Sup := λ s p hs, le_Inf' $ λ q hq, hq _ hs, | ||
Sup_le := λ s p hs, Inf_le' hs, | ||
Inf := Inf, | ||
le_Inf := λ s a, le_Inf', | ||
Inf_le := λ s a, Inf_le', | ||
..submodule.order_top, | ||
..submodule.order_bot } | ||
|
||
@[simp] theorem inf_coe : (p ⊓ q : set M) = p ∩ q := rfl | ||
|
||
@[simp] theorem mem_inf {p q : submodule R M} {x : M} : | ||
x ∈ p ⊓ q ↔ x ∈ p ∧ x ∈ q := iff.rfl | ||
|
||
@[simp] theorem Inf_coe (P : set (submodule R M)) : (↑(Inf P) : set M) = ⋂ p ∈ P, ↑p := rfl | ||
|
||
@[simp] theorem infi_coe {ι} (p : ι → submodule R M) : | ||
(↑⨅ i, p i : set M) = ⋂ i, ↑(p i) := | ||
by rw [infi, Inf_coe]; ext a; simp; exact | ||
⟨λ h i, h _ i rfl, λ h i x e, e ▸ h _⟩ | ||
|
||
@[simp] lemma mem_Inf {S : set (submodule R M)} {x : M} : x ∈ Inf S ↔ ∀ p ∈ S, x ∈ p := | ||
set.mem_bInter_iff | ||
|
||
@[simp] theorem mem_infi {ι} (p : ι → submodule R M) {x} : | ||
x ∈ (⨅ i, p i) ↔ ∀ i, x ∈ p i := | ||
by rw [← mem_coe, infi_coe, set.mem_Inter]; refl | ||
|
||
lemma mem_sup_left {S T : submodule R M} : ∀ {x : M}, x ∈ S → x ∈ S ⊔ T := | ||
show S ≤ S ⊔ T, from le_sup_left | ||
|
||
lemma mem_sup_right {S T : submodule R M} : ∀ {x : M}, x ∈ T → x ∈ S ⊔ T := | ||
show T ≤ S ⊔ T, from le_sup_right | ||
|
||
lemma mem_supr_of_mem {ι : Sort*} {b : M} {p : ι → submodule R M} (i : ι) (h : b ∈ p i) : | ||
b ∈ (⨆i, p i) := | ||
have p i ≤ (⨆i, p i) := le_supr p i, | ||
@this b h | ||
|
||
/-! Note that `submodule.mem_supr` is provided in `linear_algebra/basic.lean`. -/ | ||
|
||
lemma mem_Sup_of_mem {S : set (submodule R M)} {s : submodule R M} | ||
(hs : s ∈ S) : ∀ {x : M}, x ∈ s → x ∈ Sup S := | ||
show s ≤ Sup S, from le_Sup hs | ||
|
||
end submodule | ||
|
||
end add_comm_monoid |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters