You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
rubin-lean4/Rubin/SmulImage.lean

562 lines
17 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import Mathlib.Data.Finset.Basic
import Mathlib.GroupTheory.Subgroup.Basic
import Mathlib.GroupTheory.GroupAction.Basic
import Mathlib.Topology.Basic
import Rubin.MulActionExt
import Rubin.Topology
namespace Rubin
/--
The image of a group action (here generalized to any pair `(G, α)` implementing `SMul`)
is the image of the elements of `U` under the `g • u` operation.
An alternative definition (which is available through the [`mem_smulImage`] theorem and the [`smulImage_set`] equality) would be:
`SmulImage g U = {x | g⁻¹ • x ∈ U}`.
The notation used for this operator is `g •'' U`.
-/
def SmulImage {G α : Type _} [SMul G α] (g : G) (U : Set α) :=
(g • ·) '' U
#align subset_img Rubin.SmulImage
infixl:60 " •'' " => Rubin.SmulImage
/--
The pre-image of a group action (here generalized to any pair `(G, α)` implementing `SMul`)
is the set of values `x: α` such that `g • x ∈ U`.
Unlike [`SmulImage`], no notation is defined for this operator.
--/
def SmulPreImage {G α : Type _} [SMul G α] (g : G) (U : Set α) :=
{x | g • x ∈ U}
#align subset_preimg' Rubin.SmulPreImage
variable {G α : Type _}
variable [Group G]
variable [MulAction G α]
theorem smulImage_def {g : G} {U : Set α} : g •'' U = (· • ·) g '' U :=
rfl
#align subset_img_def Rubin.smulImage_def
theorem mem_smulImage {x : α} {g : G} {U : Set α} : x ∈ g •'' U ↔ g⁻¹ • x ∈ U :=
by
rw [Rubin.smulImage_def, Set.mem_image (g • ·) U x]
constructor
· rintro ⟨y, yU, gyx⟩
let ygx : y = g⁻¹ • x := inv_smul_smul g y ▸ Rubin.smul_congr g⁻¹ gyx
exact ygx ▸ yU
· intro h
exact ⟨g⁻¹ • x, ⟨Set.mem_preimage.mp h, smul_inv_smul g x⟩⟩
#align mem_smul'' Rubin.mem_smulImage
-- Provides a way to express a [`SmulImage`] as a `Set`;
-- this is simply [`mem_smulImage`] paired with set extensionality.
theorem smulImage_set {g: G} {U: Set α} : g •'' U = {x | g⁻¹ • x ∈ U} := Set.ext (fun _x => mem_smulImage)
@[simp]
theorem smulImage_preImage (g: G) (U: Set α) : (fun p => g • p) ⁻¹' U = g⁻¹ •'' U := by
ext x
simp
rw [mem_smulImage, inv_inv]
theorem mem_inv_smulImage {x : α} {g : G} {U : Set α} : x ∈ g⁻¹ •'' U ↔ g • x ∈ U :=
by
let msi := @Rubin.mem_smulImage _ _ _ _ x g⁻¹ U
rw [inv_inv] at msi
exact msi
#align mem_inv_smul'' Rubin.mem_inv_smulImage
@[simp]
theorem mem_smulImage' {x : α} (g : G) {U : Set α} : g • x ∈ g •'' U ↔ x ∈ U :=
by
rw [mem_smulImage]
rw [<-mul_smul, mul_left_inv, one_smul]
@[simp]
theorem smulImage_mul (g h : G) (U : Set α) : g •'' (h •'' U) = (g * h) •'' U :=
by
ext
rw [Rubin.mem_smulImage, Rubin.mem_smulImage, Rubin.mem_smulImage, ←
mul_smul, mul_inv_rev]
#align mul_smul'' Rubin.smulImage_mul
@[simp]
theorem one_smulImage (U : Set α) : (1 : G) •'' U = U :=
by
ext
rw [Rubin.mem_smulImage, inv_one, one_smul]
#align one_smul'' Rubin.one_smulImage
theorem smulImage_disjoint (g : G) {U V : Set α} :
Disjoint U V → Disjoint (g •'' U) (g •'' V) :=
by
intro disjoint_U_V
rw [Set.disjoint_left]
rw [Set.disjoint_left] at disjoint_U_V
intro x x_in_gU
by_contra h
exact (disjoint_U_V (mem_smulImage.mp x_in_gU)) (mem_smulImage.mp h)
#align disjoint_smul'' Rubin.smulImage_disjoint
theorem SmulImage.congr (g : G) {U V : Set α} : U = V → g •'' U = g •'' V :=
congr_arg fun W : Set α => g •'' W
#align smul''_congr Rubin.SmulImage.congr
theorem SmulImage.inv_congr (g: G) {U V : Set α} : g •'' U = g •'' V → U = V :=
by
intro h
rw [<-one_smulImage (G := G) U]
rw [<-one_smulImage (G := G) V]
rw [<-mul_left_inv g]
repeat rw [<-smulImage_mul]
exact SmulImage.congr g⁻¹ h
theorem smulImage_inv (g: G) (U V : Set α) : g •'' U = V ↔ U = g⁻¹ •'' V := by
nth_rw 2 [<-one_smulImage (G := G) U]
rw [<-mul_left_inv g, <-smulImage_mul]
constructor
· intro h
rw [SmulImage.congr]
exact h
· intro h
apply SmulImage.inv_congr at h
exact h
theorem smulImage_mono (g : G) {U V : Set α} : U ⊆ V → g •'' U ⊆ g •'' V := by
intro h1 x
rw [Rubin.mem_smulImage, Rubin.mem_smulImage]
exact fun h2 => h1 h2
#align smul''_subset Rubin.smulImage_mono
theorem smulImage_union (g : G) {U V : Set α} : g •'' U V = (g •'' U) (g •'' V) :=
by
ext
rw [Rubin.mem_smulImage, Set.mem_union, Set.mem_union, Rubin.mem_smulImage,
Rubin.mem_smulImage]
#align smul''_union Rubin.smulImage_union
theorem smulImage_inter (g : G) {U V : Set α} : g •'' U ∩ V = (g •'' U) ∩ (g •'' V) :=
by
ext
rw [Set.mem_inter_iff, Rubin.mem_smulImage, Rubin.mem_smulImage,
Rubin.mem_smulImage, Set.mem_inter_iff]
#align smul''_inter Rubin.smulImage_inter
@[simp]
theorem smulImage_sUnion (g : G) {S : Set (Set α)} : g •'' (⋃₀ S) = ⋃₀ {g •'' T | T ∈ S} :=
by
ext x
constructor
· intro h
rw [mem_smulImage, Set.mem_sUnion] at h
rw [Set.mem_sUnion]
let ⟨T, ⟨T_in_S, ginv_x_in_T⟩⟩ := h
simp
use T
constructor; trivial
rw [mem_smulImage]
exact ginv_x_in_T
· intro h
rw [Set.mem_sUnion] at h
rw [mem_smulImage, Set.mem_sUnion]
simp at h
let ⟨T, ⟨T_in_S, x_in_gT⟩⟩ := h
use T
constructor; trivial
rw [<-mem_smulImage]
exact x_in_gT
@[simp]
theorem smulImage_sInter (g : G) {S : Set (Set α)} : g •'' (⋂₀ S) = ⋂₀ {g •'' T | T ∈ S} := by
ext x
constructor
· intro h
rw [mem_smulImage, Set.mem_sInter] at h
rw [Set.mem_sInter]
simp
intro T T_in_S
rw [mem_smulImage]
exact h T T_in_S
· intro h
rw [Set.mem_sInter] at h
rw [mem_smulImage, Set.mem_sInter]
intro T T_in_S
rw [<-mem_smulImage]
simp at h
exact h T T_in_S
@[simp]
theorem smulImage_iInter {β : Type _} (g : G) (S : Set β) (f : β → Set α) :
g •'' (⋂ x ∈ S, f x) = ⋂ x ∈ S, g •'' (f x) :=
by
ext x
constructor
· intro h
rw [mem_smulImage] at h
simp
simp at h
intro i i_in_S
rw [mem_smulImage]
exact h i i_in_S
· intro h
simp at h
rw [mem_smulImage]
simp
intro i i_in_S
rw [<-mem_smulImage]
exact h i i_in_S
@[simp]
theorem smulImage_iInter_fin {β : Type _} (g : G) (S : Finset β) (f : β → Set α) :
g •'' (⋂ x ∈ S, f x) = ⋂ x ∈ S, g •'' (f x) :=
by
-- For some strange reason I can't use the above theorem
ext x
rw [mem_smulImage, Set.mem_iInter, Set.mem_iInter]
simp
conv => {
rhs
ext; ext
rw [mem_smulImage]
}
@[simp]
theorem smulImage_compl (g : G) (U : Set α) : (g •'' U)ᶜ = g •'' Uᶜ :=
by
ext x
rw [Set.mem_compl_iff]
repeat rw [mem_smulImage]
rw [Set.mem_compl_iff]
@[simp]
theorem smulImage_nonempty (g: G) {U : Set α} : Set.Nonempty (g •'' U) ↔ Set.Nonempty U :=
by
constructor
· intro ⟨x, x_in_gU⟩
use g⁻¹•x
rw [<-mem_smulImage]
assumption
· intro ⟨x, x_in_U⟩
use g•x
simp
assumption
theorem smulImage_eq_inv_preimage {g : G} {U : Set α} : g •'' U = (g⁻¹ • ·) ⁻¹' U :=
by
ext
constructor
· intro h; rw [Set.mem_preimage]; exact mem_smulImage.mp h
· intro h; rw [Rubin.mem_smulImage]; exact Set.mem_preimage.mp h
#align smul''_eq_inv_preimage Rubin.smulImage_eq_inv_preimage
theorem smulImage_eq_of_smul_eq {g h : G} {U : Set α} :
(∀ x ∈ U, g • x = h • x) → g •'' U = h •'' U :=
by
intro hU
ext x
rw [Rubin.mem_smulImage, Rubin.mem_smulImage]
constructor
· intro k; let a := congr_arg (h⁻¹ • ·) (hU (g⁻¹ • x) k);
simp only [smul_inv_smul, inv_smul_smul] at a ; exact Set.mem_of_eq_of_mem a k
· intro k; let a := congr_arg (g⁻¹ • ·) (hU (h⁻¹ • x) k);
simp only [smul_inv_smul, inv_smul_smul] at a ; exact Set.mem_of_eq_of_mem a.symm k
#align smul''_eq_of_smul_eq Rubin.smulImage_eq_of_smul_eq
theorem smulImage_subset_inv {G α : Type _} [Group G] [MulAction G α]
(f : G) (U V : Set α) :
f •'' U ⊆ V ↔ U ⊆ f⁻¹ •'' V :=
by
constructor
· intro h
apply smulImage_mono f⁻¹ at h
rw [smulImage_mul] at h
rw [mul_left_inv, one_smulImage] at h
exact h
· intro h
apply smulImage_mono f at h
rw [smulImage_mul] at h
rw [mul_right_inv, one_smulImage] at h
exact h
theorem smulImage_subset_inv' {G α : Type _} [Group G] [MulAction G α]
(f : G) (U V : Set α) :
f⁻¹ •'' U ⊆ V ↔ U ⊆ f •'' V :=
by
nth_rewrite 2 [<-inv_inv f]
exact smulImage_subset_inv f⁻¹ U V
theorem smulImage_disjoint_mul {G α : Type _} [Group G] [MulAction G α]
(f g : G) (U V : Set α) :
Disjoint (f •'' U) (g •'' V) ↔ Disjoint U ((f⁻¹ * g) •'' V) := by
constructor
· intro h
apply smulImage_disjoint f⁻¹ at h
repeat rw [smulImage_mul] at h
rw [mul_left_inv, one_smulImage] at h
exact h
· intro h
apply smulImage_disjoint f at h
rw [smulImage_mul] at h
rw [<-mul_assoc] at h
rw [mul_right_inv, one_mul] at h
exact h
theorem smulImage_disjoint_inv_pow {G α : Type _} [Group G] [MulAction G α]
(g : G) (i j : ) (U V : Set α) :
Disjoint (g^i •'' U) (g^j •'' V) ↔ Disjoint (g^(-j) •'' U) (g^(-i) •'' V) :=
by
rw [smulImage_disjoint_mul]
rw [<-zpow_neg, <-zpow_add, add_comm, zpow_add, zpow_neg]
rw [<-inv_inv (g^j)]
rw [<-smulImage_disjoint_mul]
simp
theorem smulImage_disjoint_subset {G α : Type _} [Group G] [MulAction G α]
{f g : G} {U V : Set α} (h_sub: U ⊆ V):
Disjoint (f •'' V) (g •'' V) → Disjoint (f •'' U) (g •'' U) :=
Set.disjoint_of_subset (smulImage_mono _ h_sub) (smulImage_mono _ h_sub)
-- States that if `g^i •'' V` and `g^j •'' V` are disjoint for any `i ≠ j` and `x ∈ V`
-- then `g^i • x` will always lie outside of `V` if `x ∈ V`.
lemma smulImage_distinct_of_disjoint_pow {G α : Type _} [Group G] [MulAction G α] {g : G} {V : Set α} {n : }
(n_pos : 0 < n)
(h_disj : ∀ (i j : Fin n), i ≠ j → Disjoint (g ^ (i : ) •'' V) (g ^ (j : ) •'' V)) :
∀ (x : α) (_hx : x ∈ V) (i : Fin n), 0 < (i : ) → g ^ (i : ) • (x : α) ∉ V :=
by
intro x hx i i_pos
have i_ne_zero : i ≠ (⟨ 0, n_pos ⟩ : Fin n) := by
intro h
rw [h] at i_pos
simp at i_pos
have h_contra : g ^ (i : ) • (x : α) ∈ g ^ (i : ) •'' V := by use x
have h_notin_V := Set.disjoint_left.mp (h_disj i (⟨0, n_pos⟩ : Fin n) i_ne_zero) h_contra
simp only [pow_zero, one_smulImage] at h_notin_V
exact h_notin_V
#align distinct_images_from_disjoint Rubin.smulImage_distinct_of_disjoint_pow
theorem smulImage_isOpen {G α : Type _}
[Group G] [TopologicalSpace α] [MulAction G α] [ContinuousConstSMul G α] (g : G)
{S : Set α} (S_open : IsOpen S) : IsOpen (g •'' S) :=
by
rw [smulImage_eq_inv_preimage]
exact (continuous_id.const_smul g⁻¹).isOpen_preimage S S_open
theorem smulImage_isClosed {G α : Type _}
[Group G] [TopologicalSpace α] [MulAction G α] [ContinuousConstSMul G α] (g : G)
{S : Set α} (S_open : IsClosed S) : IsClosed (g •'' S) :=
by
rw [<-isOpen_compl_iff]
rw [<-isOpen_compl_iff] at S_open
rw [smulImage_compl]
apply smulImage_isOpen
assumption
theorem smulImage_interior {G α : Type _} [Group G] [TopologicalSpace α] [MulAction G α]
[hc : ContinuousConstSMul G α] (g : G) (U : Set α) :
interior (g •'' U) = g •'' interior U :=
by
unfold interior
rw [smulImage_sUnion]
simp
ext x
simp
constructor
· intro ⟨T, ⟨T_open, T_sub⟩, x_in_T⟩
use g⁻¹ •'' T
repeat' apply And.intro
· exact smulImage_isOpen g⁻¹ T_open
· rw [smulImage_subset_inv]
rw [inv_inv]
exact T_sub
· rw [smulImage_mul, mul_right_inv, one_smulImage]
exact x_in_T
· intro ⟨T, ⟨T_open, T_sub⟩, x_in_T⟩
use g •'' T
repeat' apply And.intro
· exact smulImage_isOpen g T_open
· apply smulImage_mono
exact T_sub
· exact x_in_T
theorem smulImage_closure {G α : Type _} [Group G] [TopologicalSpace α] [MulAction G α]
[ContinuousConstSMul G α] (g : G) (U : Set α) :
closure (g •'' U) = g •'' closure U :=
by
unfold closure
rw [smulImage_sInter]
simp
ext x
simp
constructor
· intro IH T' T T_closed U_ss_T T'_eq
rw [<-T'_eq]
clear T' T'_eq
apply IH
· exact smulImage_isClosed g T_closed
· apply smulImage_mono
exact U_ss_T
· intro IH T T_closed gU_ss_T
apply IH
· exact smulImage_isClosed g⁻¹ T_closed
· rw [<-smulImage_subset_inv]
exact gU_ss_T
· simp
section Filters
open Topology
variable {G α : Type _}
variable [Group G] [MulAction G α]
/--
An SMul can be extended to filters, while preserving the properties of `MulAction`.
To avoid polluting the `SMul` instances for filters, those properties are made separate,
instead of implementing `MulAction G (Filter α)`.
--/
def SmulFilter {G α : Type _} [SMul G α] (g : G) (F : Filter α) : Filter α :=
Filter.map (fun p => g • p) F
infixl:60 " •ᶠ " => Rubin.SmulFilter
theorem smulFilter_def {G α : Type _} [SMul G α] (g : G) (F : Filter α) :
Filter.map (fun p => g • p) F = g •ᶠ F := rfl
theorem smulFilter_neBot {G α : Type _} [SMul G α] (g : G) {F : Filter α} (F_neBot : Filter.NeBot F) :
Filter.NeBot (g •ᶠ F) :=
by
rw [<-smulFilter_def]
exact Filter.map_neBot
instance smulFilter_neBot' {G α : Type _} [SMul G α] {g : G} {F : Filter α} [F_neBot : Filter.NeBot F] :
Filter.NeBot (g •ᶠ F) := smulFilter_neBot g F_neBot
theorem smulFilter_principal (g : G) (S : Set α) :
g •ᶠ Filter.principal S = Filter.principal (g •'' S) :=
by
rw [<-smulFilter_def]
rw [Filter.map_principal]
rfl
theorem mul_smulFilter (g h: G) (F : Filter α) :
(g * h) •ᶠ F = g •ᶠ (h •ᶠ F) :=
by
repeat rw [<-smulFilter_def]
simp only [mul_smul]
rw [Filter.map_map]
rfl
theorem one_smulFilter (G : Type _) [Group G] [MulAction G α] (F : Filter α) :
(1 : G) •ᶠ F = F :=
by
rw [<-smulFilter_def]
simp only [one_smul]
exact Filter.map_id
theorem mem_smulFilter_iff (g : G) (F : Filter α) (U : Set α) :
U ∈ g •ᶠ F ↔ g⁻¹ •'' U ∈ F :=
by
rw [<-smulFilter_def, Filter.mem_map, smulImage_eq_inv_preimage, inv_inv]
theorem smulFilter_mono (g : G) (F F' : Filter α) :
F ≤ F' ↔ g •ᶠ F ≤ g •ᶠ F' :=
by
suffices ∀ (g : G) (F F' : Filter α), F ≤ F' → g •ᶠ F ≤ g •ᶠ F' by
constructor
apply this
intro H
specialize this g⁻¹ _ _ H
repeat rw [<-mul_smulFilter] at this
rw [mul_left_inv] at this
repeat rw [one_smulFilter] at this
exact this
intro g F F' F_le_F'
intro U U_in_gF
rw [mem_smulFilter_iff] at U_in_gF
rw [mem_smulFilter_iff]
apply F_le_F'
assumption
theorem smulFilter_le_iff_le_inv (g : G) (F F' : Filter α) :
F ≤ g •ᶠ F' ↔ g⁻¹ •ᶠ F ≤ F' :=
by
nth_rw 2 [<-one_smulFilter G F']
rw [<-mul_left_inv g, mul_smulFilter]
exact smulFilter_mono g⁻¹ _ _
variable [TopologicalSpace α]
theorem smulFilter_nhds (g : G) (p : α) [ContinuousConstSMul G α]:
g •ᶠ 𝓝 p = 𝓝 (g • p) :=
by
ext S
rw [<-smulFilter_def, Filter.mem_map, mem_nhds_iff, mem_nhds_iff]
simp
constructor
· intro ⟨T, T_ss_smulImage, T_open, p_in_T⟩
use g •'' T
repeat' apply And.intro
· rw [smulImage_subset_inv]
assumption
· exact smulImage_isOpen g T_open
· simp
assumption
· intro ⟨T, T_ss_S, T_open, gp_in_T⟩
use g⁻¹ •'' T
repeat' apply And.intro
· apply smulImage_mono
assumption
· exact smulImage_isOpen g⁻¹ T_open
· rw [mem_smulImage, inv_inv]
assumption
theorem smulFilter_clusterPt (g : G) (F : Filter α) (x : α) [ContinuousConstSMul G α] :
ClusterPt x (g •ᶠ F) ↔ ClusterPt (g⁻¹ • x) F :=
by
suffices ∀ (g : G) (F : Filter α) (x : α), ClusterPt x (g •ᶠ F) → ClusterPt (g⁻¹ • x) F by
constructor
apply this
intro gx_clusterPt_F
rw [<-one_smul G x, <-mul_right_inv g, mul_smul]
nth_rw 1 [<-inv_inv g]
apply this
rw [<-mul_smulFilter, mul_left_inv, one_smulFilter]
assumption
intro g F x x_cp_gF
rw [clusterPt_iff_forall_mem_closure]
rw [clusterPt_iff_forall_mem_closure] at x_cp_gF
simp only [mem_smulFilter_iff] at x_cp_gF
intro S S_in_F
rw [<-mem_inv_smulImage]
rw [<-smulImage_closure]
apply x_cp_gF
rw [inv_inv, smulImage_mul, mul_left_inv, one_smulImage]
assumption
theorem smulImage_compact [ContinuousConstSMul G α] (g : G) {U : Set α} (U_compact : IsCompact U) :
IsCompact (g •'' U) :=
by
intro F F_neBot F_le_principal
rw [<-smulFilter_principal, smulFilter_le_iff_le_inv] at F_le_principal
let ⟨x, x_in_U, x_clusterPt⟩ := U_compact F_le_principal
use g • x
constructor
· rw [mem_smulImage']
assumption
· rw [smulFilter_clusterPt, inv_inv] at x_clusterPt
assumption
end Filters
end Rubin