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/AlgebraicDisjointness.lean

633 lines
19 KiB

import Mathlib.GroupTheory.GroupAction.Basic
import Mathlib.GroupTheory.Subgroup.Basic
import Mathlib.GroupTheory.Subgroup.Actions
import Mathlib.GroupTheory.Commutator
import Mathlib.Topology.Basic
import Mathlib.Topology.Algebra.ConstMulAction
import Mathlib.Data.Fintype.Perm
import Mathlib.Tactic.FinCases
import Mathlib.Tactic.IntervalCases
import Rubin.RigidStabilizer
import Rubin.SmulImage
import Rubin.Topology
import Rubin.FaithfulAction
import Rubin.Period
import Rubin.LocallyDense
namespace Rubin
variable {G : Type _} [Group G]
theorem Commute.conj (f g h : G) : Commute (f * g * f⁻¹) h ↔ Commute g (f⁻¹ * h * f) := by
suffices ∀ (f g h : G), Commute (f * g * f⁻¹) h → Commute g (f⁻¹ * h * f) by
constructor
· apply this
· intro cg
symm
nth_rw 1 [<-inv_inv f]
apply this
symm
rw [inv_inv]
exact cg
intro f g h fgf_h_comm
unfold Commute SemiconjBy at *
rw [<-mul_assoc, <-mul_assoc]
rw [<-mul_assoc, <-mul_assoc] at fgf_h_comm
have gfh_eq : g * f⁻¹ * h = f⁻¹ * h * f * g * f⁻¹ := by
repeat rw [mul_assoc f⁻¹]
rw [<-fgf_h_comm]
group
rw [gfh_eq]
group
theorem Commute.conj' (f g h : G) : Commute (f⁻¹ * g * f) h ↔ Commute g (f * h * f⁻¹) := by
nth_rw 2 [<-inv_inv f]
nth_rw 3 [<-inv_inv f]
apply Commute.conj
structure AlgebraicallyDisjointElem (f g h : G) :=
non_commute: ¬Commute f h
fst : G
snd : G
fst_commute : Commute fst g
snd_commute : Commute snd g
comm_elem_commute : Commute ⁅fst, ⁅snd, h⁆⁆ g
comm_elem_nontrivial : ⁅fst, ⁅snd, h⁆⁆ ≠ 1
namespace AlgebraicallyDisjointElem
def comm_elem {f g h : G} (disj_elem : AlgebraicallyDisjointElem f g h) : G :=
⁅disj_elem.fst, ⁅disj_elem.snd, h⁆⁆
@[simp]
theorem comm_elem_eq {f g h : G} (disj_elem : AlgebraicallyDisjointElem f g h) :
disj_elem.comm_elem = ⁅disj_elem.fst, ⁅disj_elem.snd, h⁆⁆ :=
by
unfold comm_elem
simp
lemma comm_elem_conj (f g h i : G) :
⁅i * f * i⁻¹, ⁅i * g * i⁻¹, i * h * i⁻¹⁆⁆ = i * ⁅f, ⁅g, h⁆⁆ * i⁻¹ := by group
theorem conj {f g h : G} (disj_elem : AlgebraicallyDisjointElem f g h) (i : G): AlgebraicallyDisjointElem (i * f * i⁻¹) (i * g * i⁻¹) (i * h * i⁻¹) where
non_commute := by
rw [Commute.conj]
group
exact disj_elem.non_commute
fst := i * disj_elem.fst * i⁻¹
snd := i * disj_elem.snd * i⁻¹
fst_commute := by
rw [Commute.conj]
group
exact disj_elem.fst_commute
snd_commute := by
rw [Commute.conj]
group
exact disj_elem.snd_commute
comm_elem_nontrivial := by
intro eq_one
apply disj_elem.comm_elem_nontrivial
rw [comm_elem_conj, <-mul_right_inv i] at eq_one
apply mul_right_cancel at eq_one
nth_rw 2 [<-mul_one i] at eq_one
apply mul_left_cancel at eq_one
exact eq_one
comm_elem_commute := by
rw [comm_elem_conj, Commute.conj]
rw [(by group : i⁻¹ * (i * g * i⁻¹) * i = g)]
exact disj_elem.comm_elem_commute
end AlgebraicallyDisjointElem
-- Also known as `η_G(f)`.
/--
A pair (f, g) is said to be "algebraically disjoint" if it can produce an instance of
[`AlgebraicallyDisjointElem`] for any element `h ∈ G` such that `f` and `h` don't commute.
In other words, `g` is algebraically disjoint from `f` if `∀ h ∈ G`, with `⁅f, h⁆ ≠ 1`,
there exists a pair `f₁, f₂ ∈ Centralizer(g, G)`,
so that `⁅f₁, ⁅f₂, h⁆⁆` is a nontrivial element of `Centralizer(g, G)`.
Here the definition of `k ∈ Centralizer(g, G)` is directly unrolled as `Commute k g`.
This is a slightly weaker proposition than plain disjointness,
but it is easier to derive from the hypothesis of Rubin's theorem.
-/
def AlgebraicallyDisjoint {G : Type _} [Group G] (f g : G) :=
∀ (h : G), ¬Commute f h → AlgebraicallyDisjointElem f g h
theorem AlgebraicallyDisjoint_mk {G : Type _} [Group G] {f g : G}
(mk_thm : ∀ h : G, ¬Commute f h →
∃ f₁ f₂ : G, Commute f₁ g ∧ Commute f₂ g ∧ Commute ⁅f₁, ⁅f₂, h⁆⁆ g ∧ ⁅f₁, ⁅f₂, h⁆⁆ ≠ 1
) : AlgebraicallyDisjoint f g :=
fun (h : G) (nc : ¬Commute f h) => {
non_commute := nc,
fst := (mk_thm h nc).choose
snd := (mk_thm h nc).choose_spec.choose
fst_commute := (mk_thm h nc).choose_spec.choose_spec.left
snd_commute := (mk_thm h nc).choose_spec.choose_spec.right.left
comm_elem_commute := (mk_thm h nc).choose_spec.choose_spec.right.right.left
comm_elem_nontrivial := by
exact (mk_thm h nc).choose_spec.choose_spec.right.right.right
}
/--
This definition simply wraps `AlgebraicallyDisjoint` as a `Prop`.
It is equivalent to it, although since `AlgebraicallyDisjoint` isn't a `Prop`,
an `↔` (iff) statement joining the two cannot be written.
You should consider using it when proving `↔`/`∧` kinds of theorems, or when tools like `cases` are needed,
as the base `AlgebraicallyDisjoint` isn't a `Prop` and won't work with those.
The two `Coe` and `CoeFn` instances provided around this type make it essentially transparent —
you can use an instance of `AlgebraicallyDisjoint` in place of a `IsAlgebraicallyDisjoint` and vice-versa.
You might need to add the odd `↑` (coe) operator to make Lean happy.
--/
def IsAlgebraicallyDisjoint {G : Type _} [Group G] (f g : G): Prop :=
∀ (h : G), ¬Commute f h → ∃ (f₁ f₂ : G), ∃ (elem : AlgebraicallyDisjointElem f g h), elem.fst = f₁ ∧ elem.snd = f₂
namespace IsAlgebraicallyDisjoint
variable {G : Type _} [Group G]
variable {f g: G}
noncomputable def elim
(is_alg_disj: IsAlgebraicallyDisjoint f g) :
AlgebraicallyDisjoint f g :=
fun h nc => (is_alg_disj h nc).choose_spec.choose_spec.choose
def mk (alg_disj : AlgebraicallyDisjoint f g) : IsAlgebraicallyDisjoint f g :=
fun h nc =>
let elem := alg_disj h nc
elem.fst,
elem.snd,
elem,
rfl,
rfl
noncomputable instance coeFnAlgebraicallyDisjoint : CoeFun
(IsAlgebraicallyDisjoint f g)
(fun _ => AlgebraicallyDisjoint f g) where
coe := elim
instance coeAlgebraicallyDisjoint : Coe (AlgebraicallyDisjoint f g) (IsAlgebraicallyDisjoint f g) where
coe := mk
theorem conj (is_alg_disj : IsAlgebraicallyDisjoint f g) (h : G) :
IsAlgebraicallyDisjoint (h * f * h⁻¹) (h * g * h⁻¹) :=
by
apply elim at is_alg_disj
apply mk
intro i nc
rw [Commute.conj] at nc
rw [(by group : i = h * (h⁻¹ * i * h) * h⁻¹)]
exact (is_alg_disj (h⁻¹ * i * h) nc).conj h
end IsAlgebraicallyDisjoint
-- TODO: find a better home for these lemmas
variable {G α : Type _}
variable [Group G]
variable [TopologicalSpace α]
variable [MulAction G α]
variable [ContinuousConstSMul G α]
variable [FaithfulSMul G α]
-- Kind of a boring lemma but okay
lemma rewrite_Union (f : Fin 2 × Fin 2 → Set α) :
((i : Fin 2 × Fin 2), f i) = (f (0,0) f (0,1)) (f (1,0) f (1,1)) :=
by
ext x
simp only [Set.mem_iUnion, Set.mem_union]
constructor
· rewrite [forall_exists_index]
intro i
fin_cases i
<;> simp only [Fin.zero_eta, Fin.mk_one]
<;> intro h
<;> simp only [h, true_or, or_true]
· rintro ((h|h)|(h|h)) <;> exact ⟨_, h⟩
lemma smul_inj_moves {ι : Type*} [Fintype ι] [T2Space α]
{f : ι → G} {x : α} {i j : ι} (i_ne_j : i ≠ j)
(f_smul_inj : Function.Injective (fun i : ι => (f i) • x)) :
((f j)⁻¹ * f i) • x ≠ x := by
by_contra h
apply i_ne_j
apply f_smul_inj
group_action
group at h
exact h
def smul_inj_nbhd {ι : Type*} [Fintype ι] [T2Space α]
{f : ι → G} {x : α} {i j : ι} (i_ne_j : i ≠ j)
(f_smul_inj : Function.Injective (fun i : ι => (f i) • x)) :
Set α :=
(disjoint_nbhd (smul_inj_moves i_ne_j f_smul_inj)).choose
lemma smul_inj_nbhd_open {ι : Type*} [Fintype ι] [T2Space α]
{f : ι → G} {x : α} {i j : ι} (i_ne_j : i ≠ j)
(f_smul_inj : Function.Injective (fun i : ι => (f i) • x)) :
IsOpen (smul_inj_nbhd i_ne_j f_smul_inj) :=
by
exact (disjoint_nbhd (smul_inj_moves i_ne_j f_smul_inj)).choose_spec.1
lemma smul_inj_nbhd_mem {ι : Type*} [Fintype ι] [T2Space α]
{f : ι → G} {x : α} {i j : ι} (i_ne_j : i ≠ j)
(f_smul_inj : Function.Injective (fun i : ι => (f i) • x)) :
x ∈ (smul_inj_nbhd i_ne_j f_smul_inj) :=
by
exact (disjoint_nbhd (smul_inj_moves i_ne_j f_smul_inj)).choose_spec.2.1
lemma smul_inj_nbhd_disjoint {ι : Type*} [Fintype ι] [T2Space α]
{f : ι → G} {x : α} {i j : ι} (i_ne_j : i ≠ j)
(f_smul_inj : Function.Injective (fun i : ι => (f i) • x)) :
Disjoint
(smul_inj_nbhd i_ne_j f_smul_inj)
((f j)⁻¹ * f i •'' (smul_inj_nbhd i_ne_j f_smul_inj)) :=
by
exact (disjoint_nbhd (smul_inj_moves i_ne_j f_smul_inj)).choose_spec.2.2
lemma disjoint_nbhd_fin {ι : Type*} [Fintype ι] [T2Space α]
{f : ι → G} {x : α} (f_smul_inj : Function.Injective (fun i : ι => (f i) • x)):
∃ U : Set α,
IsOpen U ∧ x ∈ U ∧ (∀ (i j : ι), i ≠ j → Disjoint (f i •'' U) (f j •'' U)) :=
by
let ι₂ := { p : ι × ι | p.1 ≠ p.2 }
let U := ⋂(p : ι₂), smul_inj_nbhd p.prop f_smul_inj
use U
repeat' apply And.intro
· apply isOpen_iInter_of_finite
intro ⟨⟨i, j⟩, i_ne_j⟩
apply smul_inj_nbhd_open
· apply Set.mem_iInter.mpr
intro ⟨⟨i, j⟩, i_ne_j⟩
apply smul_inj_nbhd_mem
· intro i j i_ne_j
-- We transform `Disjoint (f i •'' U) (f j •'' U)` into `Disjoint N ((f i)⁻¹ * f j •'' N)`
let N := smul_inj_nbhd i_ne_j f_smul_inj
have U_subset_N : U ⊆ N := Set.iInter_subset
(fun (⟨⟨i, j⟩, i_ne_j⟩ : ι₂) => (smul_inj_nbhd i_ne_j f_smul_inj))
⟨⟨i, j⟩, i_ne_j⟩
rw [disjoint_comm, smulImage_disjoint_mul]
apply Set.disjoint_of_subset U_subset_N
· apply smulImage_mono
exact U_subset_N
· exact smul_inj_nbhd_disjoint i_ne_j f_smul_inj
lemma moves_inj {g : G} {x : α} {n : } (period_ge_n : ∀ (k : ), 1 ≤ k → k < n → g^k • x ≠ x) :
Function.Injective (fun (i : Fin n) => g^(i : ) • x) :=
by
intro a b same_img
by_contra a_ne_b
let abs_diff := |(a : ) - (b : )|
apply period_ge_n abs_diff _ _ _
{
show 1 ≤ abs_diff
unfold_let
rw [<-zero_add 1, Int.add_one_le_iff]
apply abs_pos.mpr
apply sub_ne_zero.mpr
simp
apply Fin.vne_of_ne
apply a_ne_b
}
{
show abs_diff < (n : )
apply abs_lt.mpr
constructor
· rw [<-zero_sub]
apply Int.sub_lt_sub_of_le_of_lt <;> simp
· rw [<-sub_zero (n : )]
apply Int.sub_lt_sub_of_lt_of_le <;> simp
}
{
show g^abs_diff • x = x
simp at same_img
group_action at same_img
rw [neg_add_eq_sub] at same_img
cases abs_cases ((a : ) - (b : )) with
| inl h =>
unfold_let
rw [h.1]
exact same_img
| inr h =>
unfold_let
rw [h.1]
rw [smul_eq_iff_eq_inv_smul]
group
symm
exact same_img
}
-- Note: this can be strengthened to `k ≥ 0`
lemma natAbs_eq_of_pos' (k : ) (k_ge_one : k ≥ 1) : k = k.natAbs := by
cases Int.natAbs_eq k with
| inl _ => assumption
| inr h =>
exfalso
have k_lt_one : k < 1 := by
calc
k ≤ 0 := by
rw [h]
apply nonpos_of_neg_nonneg
rw [neg_neg]
apply Int.ofNat_nonneg
_ < 1 := by norm_num
exact ((lt_iff_not_ge _ _).mp k_lt_one) k_ge_one
lemma period_ge_n_cast {g : G} {x : α} {n : } :
(∀ (k : ), 1 ≤ k → k < n → g ^ k • x ≠ x) →
(∀ (k : ), 1 ≤ k → k < n → g ^ k • x ≠ x) :=
by
intro period_ge_n'
intro k one_le_k k_lt_n
have one_le_abs_k : 1 ≤ k.natAbs := by
rw [<-Nat.cast_le (α := )]
norm_num
calc
1 ≤ k := one_le_k
_ ≤ |k| := le_abs_self k
have abs_k_lt_n : k.natAbs < n := by
rw [<-Nat.cast_lt (α := )]
norm_num
calc
|k| = k := abs_of_pos one_le_k
_ < n := k_lt_n
have res := period_ge_n' k.natAbs one_le_abs_k abs_k_lt_n
rw [<-zpow_ofNat, Int.coe_natAbs, abs_of_pos _] at res
exact res
exact one_le_k
instance {g : G} {x : α} {n : } :
Coe
(∀ (k : ), 1 ≤ k → k < n → g ^ k • x ≠ x)
(∀ (k : ), 1 ≤ k → k < n → g ^ k • x ≠ x)
where
coe := period_ge_n_cast
-- TODO: remove the unneeded `n` parameter
theorem smul_injective_within_period {g : G} {p : α} {n : }
(period_eq_n : Period.period p g = n) :
Function.Injective (fun (i : Fin n) => g ^ (i : ) • p) :=
by
simp only [<-zpow_coe_nat]
apply moves_inj
intro k one_le_k k_lt_n
apply Period.moves_within_period'
exact one_le_k
rw [period_eq_n]
exact k_lt_n
#align moves_inj_period Rubin.smul_injective_within_period
/-
The algebraic centralizer (and its associated basis) allow for a purely group-theoretic construction of the
`RegularSupport` sets.
They are defined as the centralizers of the subgroups `{g^12 | g ∈ G ∧ AlgebraicallyDisjoint f g}`
-/
section AlgebraicCentralizer
variable {G : Type _}
variable [Group G]
-- TODO: prove this is a subgroup?
-- This is referred to as `ξ_G^12(f)`
def AlgebraicSubgroup (f : G) : Set G :=
(fun g : G => g^12) '' { g : G | IsAlgebraicallyDisjoint f g }
def AlgebraicCentralizer (f : G) : Subgroup G :=
Subgroup.centralizer (AlgebraicSubgroup f)
theorem AlgebraicSubgroup.conj (f g : G) :
(fun h => g * h * g⁻¹) '' AlgebraicSubgroup f = AlgebraicSubgroup (g * f * g⁻¹) :=
by
unfold AlgebraicSubgroup
rw [Set.image_image]
have gxg12_eq : ∀ x : G, g * x^12 * g⁻¹ = (g * x * g⁻¹)^12 := by
simp
simp only [gxg12_eq]
ext x
simp
constructor
· intro ⟨y, y_disj, x_eq⟩
use g * y * g⁻¹
rw [<-gxg12_eq]
exact ⟨y_disj.conj g, x_eq⟩
· intro ⟨y, y_disj, x_eq⟩
use g⁻¹ * y * g
constructor
· convert y_disj.conj g⁻¹ using 1
all_goals group
· nth_rw 3 [<-inv_inv g]
simp only [conj_pow]
rw [x_eq]
group
@[simp]
theorem AlgebraicCentralizer.conj (f g : G) :
(fun h => g * h * g⁻¹) '' AlgebraicCentralizer f = AlgebraicCentralizer (g * f * g⁻¹) :=
by
unfold AlgebraicCentralizer
ext x
simp [Subgroup.mem_centralizer_iff]
constructor
· intro ⟨y, ⟨x_comm, x_eq⟩⟩
intro h h_in_alg
rw [<-AlgebraicSubgroup.conj] at h_in_alg
simp at h_in_alg
let ⟨i, i_in_alg, gig_eq_h⟩ := h_in_alg
specialize x_comm i i_in_alg
rw [<-gig_eq_h, <-x_eq]
group
rw [mul_assoc _ i, x_comm, <-mul_assoc]
· intro x_comm
use g⁻¹ * x * g
group
simp
intro h h_in_alg
simp [<-AlgebraicSubgroup.conj] at x_comm
specialize x_comm h h_in_alg
have h₁ : g⁻¹ * x * g * h = g⁻¹ * (g * h * g⁻¹ * x) * g := by
rw [x_comm]
group
rw [h₁]
group
/--
Finite intersections of [`AlgebraicCentralizer`].
--/
def AlgebraicCentralizerInter (S : Finset G) : Subgroup G :=
⨅ (g ∈ S), AlgebraicCentralizer g
def AlgebraicCentralizerBasis (G : Type _) [Group G] : Set (Set G) :=
{ S : Set G | S ≠ {1} ∧ ∃ seed : Finset G,
S = AlgebraicCentralizerInter seed
}
theorem AlgebraicCentralizerBasis.mem_iff (S : Set G) :
S ∈ AlgebraicCentralizerBasis G ↔
S ≠ {1} ∧ ∃ seed : Finset G, S = AlgebraicCentralizerInter seed
:= by rfl
theorem AlgebraicCentralizerBasis.subgroup_mem_iff (S : Subgroup G) :
(S : Set G) ∈ AlgebraicCentralizerBasis G ↔
S ≠ ⊥ ∧ ∃ seed : Finset G, S = AlgebraicCentralizerInter seed :=
by
rw [mem_iff, <-Subgroup.coe_bot, ne_eq, SetLike.coe_set_eq]
simp
theorem AlgebraicCentralizerBasis.empty_not_mem : ∅ ∉ AlgebraicCentralizerBasis G := by
simp [AlgebraicCentralizerBasis]
intro _ _
rw [<-ne_eq]
symm
rw [<-Set.nonempty_iff_ne_empty]
exact Subgroup.coe_nonempty _
theorem AlgebraicCentralizerBasis.to_subgroup {S : Set G} (S_in_basis : S ∈ AlgebraicCentralizerBasis G):
∃ S' : Subgroup G, S = S' :=
by
rw [mem_iff] at S_in_basis
let ⟨_, ⟨seed, S_eq⟩⟩ := S_in_basis
use AlgebraicCentralizerInter seed
theorem Set.image_equiv_eq {α β : Type _} (S : Set α) (T : Set β) (f : α ≃ β) :
f '' S = T ↔ S = f.symm '' T :=
by
constructor
· intro fS_eq_T
ext x
rw [<-fS_eq_T]
simp
· intro S_eq_fT
ext x
rw [S_eq_fT]
simp
theorem AlgebraicCentralizerBasis.univ_mem (ex_non_trivial : ∃ g : G, g ≠ 1): Set.univ ∈ AlgebraicCentralizerBasis G := by
rw [mem_iff]
constructor
symm
exact Set.nonempty_compl.mp ex_non_trivial
use ∅
simp [AlgebraicCentralizerInter]
theorem AlgebraicCentralizerBasis.conj_mem {S : Set G} (S_in_basis : S ∈ AlgebraicCentralizerBasis G)
(h : G) : (fun g => h * g * h⁻¹) '' S ∈ AlgebraicCentralizerBasis G :=
by
let ⟨S', S_eq⟩ := to_subgroup S_in_basis
rw [S_eq]
rw [S_eq, subgroup_mem_iff] at S_in_basis
rw [mem_iff]
have conj_eq : (fun g => h * g * h⁻¹) = (MulAut.conj h).toEquiv := by
ext x
simp
constructor
· rw [conj_eq]
rw [ne_eq, Set.image_equiv_eq]
simp
rw [<-Subgroup.coe_bot, SetLike.coe_set_eq]
exact S_in_basis.left
· let ⟨seed, S'_eq⟩ := S_in_basis.right
have dec_eq : DecidableEq G := Classical.typeDecidableEq _
use Finset.image (fun g => h * g * h⁻¹) seed
rw [S'_eq]
unfold AlgebraicCentralizerInter
ext g
rw [conj_eq]
rw [Set.mem_image_equiv]
simp
conv => {
rhs
intro
intro
rw [<-SetLike.mem_coe, <-AlgebraicCentralizer.conj, conj_eq, Set.mem_image_equiv]
}
theorem AlgebraicCentralizerBasis.inter_closed
{S T : Set G} (S_in_basis : S ∈ AlgebraicCentralizerBasis G) (T_in_basis : T ∈ AlgebraicCentralizerBasis G)
(ST_ne_bot : S ∩ T ≠ {1}) :
S ∩ T ∈ AlgebraicCentralizerBasis G :=
by
let ⟨S', S_eq⟩ := to_subgroup S_in_basis
rw [S_eq]
rw [S_eq, subgroup_mem_iff] at S_in_basis
let ⟨S'_ne_bot, ⟨S'_seed, S'_eq⟩⟩ := S_in_basis
let ⟨T', T_eq⟩ := to_subgroup T_in_basis
rw [T_eq]
rw [T_eq, subgroup_mem_iff] at T_in_basis
let ⟨T'_ne_bot, ⟨T'_seed, T'_eq⟩⟩ := T_in_basis
rw [<-Subgroup.coe_inf, subgroup_mem_iff]
rw [S_eq, T_eq, <-Subgroup.coe_inf, <-Subgroup.coe_bot, ne_eq, SetLike.coe_set_eq, <-ne_eq] at ST_ne_bot
have dec_eq : DecidableEq G := Classical.typeDecidableEq G
refine ⟨ST_ne_bot, ⟨S'_seed T'_seed, ?inter_eq⟩⟩
unfold AlgebraicCentralizerInter
simp only [<-Finset.mem_coe]
rw [Finset.coe_union, iInf_union]
rw [S'_eq, T'_eq]
rfl
def MulAut.conj_order_iso (g : G) : Set G ≃o Set G := (MulAut.conj g).toEquiv.toOrderIsoSet
theorem AlgebraicCentralizerBasis.eq_conj_self (g : G) :
(MulAut.conj_order_iso g) '' AlgebraicCentralizerBasis G = AlgebraicCentralizerBasis G :=
by
ext S
simp [MulAut.conj_order_iso]
conv => {
lhs
congr; intro x
rw [Equiv.toOrderIsoSet_apply]
}
simp
constructor
· intro ⟨T, T_in_basis, T_eq⟩
rw [<-T_eq]
exact conj_mem T_in_basis g
· intro S_in_basis
use (fun h => g⁻¹ * h * g⁻¹⁻¹) '' S
refine ⟨conj_mem S_in_basis g⁻¹, ?S_eq⟩
rw [Set.image_image]
group
rw [Set.image_id']
theorem AlgebraicCentralizerBasis.conj_mem' {S : Set G} (S_in_basis : S ∈ AlgebraicCentralizerBasis G) (g : G) :
(MulAut.conj_order_iso g) S ∈ AlgebraicCentralizerBasis G :=
by
show (fun i => g * i * g⁻¹) '' S ∈ AlgebraicCentralizerBasis G
exact conj_mem S_in_basis g
end AlgebraicCentralizer
end Rubin