/- Copyright (c) 2024 Judith Ludwig, Christian Merten. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Judith Ludwig, Christian Merten -/ import BruhatTits.Graph.Graph import BruhatTits.Utils.GraphAction /-! # Group actions on the Bruhat-Tits graph In this file we equip the Bruhat-Tits graph with group actions of `GL₂(K)` and compute stabilizers. # Main results - `MulAction.IsPretransitive (GL (Fin 2) K) (Vertices R)` : We show that `GL₂(K)` acts transitively on the vertices. - `GraphAction (GL (Fin 2) K) (BTgraph (R:= R))` : The group `GL₂(K)` acts on `BTgraph`. - `stabilizer_mk_standard_eq_sup` : The stabilizer of the standard vertex of the `GL₂(K)`-action is `Kˣ * GL₂(R)`. -/ -- Let R be a discrete valuation ring and K its field of fractions variable {K : Type*} [Field K] variable {R : Subring K} namespace BruhatTits section Action lemma isSimilar_smul_of_isSimilar (g : GL (Fin 2) K) (L M : Lattice R) (h : L.IsSimilar R M) : (g • L).IsSimilar R (g • M) := by obtain ⟨a, rfl⟩ := h have : g • a • L = a • g • L := by apply Lattice.ext simp only [Lattice.smul_M, Lattice.smul_module, Units.smul_def] ext x simp only [Matrix.GeneralLinearGroup.mem_smul] constructor · rintro ⟨y, ⟨z, hz, rfl⟩, rfl⟩ simp only [DistribMulAction.toLinearMap_apply, Matrix.mulVec_smul] refine ⟨g.val.mulVec z, ?_, rfl⟩ simp only [SetLike.mem_coe, Matrix.GeneralLinearGroup.mem_smul] use z, hz · rintro ⟨y, hy, rfl⟩ simp only [SetLike.mem_coe, Matrix.GeneralLinearGroup.mem_smul] at hy obtain ⟨z, hz, rfl⟩ := hy refine ⟨a.val • z, ?_, ?_⟩ · use z, hz rfl · simp [Matrix.mulVec_smul] rw [this] exact Lattice.isSimilar_smul R (g • L) a def smulGL (g : GL (Fin 2) K) : Vertices R → Vertices R := Quotient.lift (fun L ↦ ⟦g • L⟧) <| by intro L M h apply Quotient.sound exact isSimilar_smul_of_isSimilar g L M h lemma smulGL_mk (g : GL (Fin 2) K) (L : Lattice R) : smulGL g ⟦L⟧ = ⟦g • L⟧ := rfl instance : SMul (GL (Fin 2) K) (Vertices R) where smul := smulGL lemma Vertices.smul_def (g : GL (Fin 2) K) (x : Vertices R) : g • x = smulGL g x := rfl /-- The action of `GL₂(K)` on vertices. -/ instance : MulAction (GL (Fin 2) K) (Vertices R) where one_smul x := by refine Quotient.inductionOn x (fun L ↦ ?_) rw [Vertices.smul_def, smulGL_mk, one_smul] mul_smul g h x := by refine Quotient.inductionOn x (fun L ↦ ?_) rw [Vertices.smul_def, smulGL_mk] rw [mul_smul] rw [← smulGL_mk, ← Vertices.smul_def] rw [← smulGL_mk, ← Vertices.smul_def] variable [IsDiscreteValuationRing R] [IsFractionRing R K] /-- `GL₂(K)` acts transitively on the vertices. -/ instance : MulAction.IsPretransitive (GL (Fin 2) K) (Vertices R) where exists_smul_eq L M := by classical induction' L using Quotient.inductionOn with L induction' M using Quotient.inductionOn with M obtain ⟨g, rfl⟩ := MulAction.exists_smul_eq (GL (Fin 2) K) L M use g rfl @[simp] lemma inv_smul_smul_eq_inv (g : GL (Fin 2) K) (x y : Vertices R) : inv (g • x) (g • y) = inv x y := by refine Quotient.inductionOn₂ x y (fun L M ↦ ?_) rw [Vertices.smul_def, smulGL_mk] rw [Vertices.smul_def, smulGL_mk] show dist (g • L) (g • M) = dist L M simp @[simp] lemma adj_smul_smul_iff_adj (g : GL (Fin 2) K) (x y : Vertices R) : BTgraph.Adj (g • x) (g • y) ↔ BTgraph.Adj x y := by show inv (g • x) (g • y) = 1 ↔ inv x y = 1 simp /-- `GL₂(K)` acts by graph isomorphisms on the Bruhat-Tits tree. -/ def _root_.Matrix.GeneralLinearGroup.toGraphIso (g : GL (Fin 2) K) : BTgraph (R := R) ≃g BTgraph (R := R) where toEquiv := MulAction.toPerm g map_rel_iff' {x y} := by simp /-- The action of `GL₂(K)` on the Bruhat-Tits graph. -/ instance : GraphAction (GL (Fin 2) K) (BTgraph (R:= R)) where smul_adj_smul g x y := (adj_smul_smul_iff_adj g x y).mpr omit [IsDiscreteValuationRing ↥R] [IsFractionRing (↥R) K] in lemma cartanDiag_smul_standard (ϖ : R) (hϖ : Irreducible ϖ) (f : Fin 2 → ℤ) : cartanDiag ϖ hϖ f • Lattice.standard R = ((Pi.basisFun K (Fin 2)).twist hϖ f).toLattice := by simp only [Lattice.standard] have : cartanDiag ϖ hϖ f • ((Pi.basisFun K (Fin 2))) = (((Pi.basisFun K (Fin 2)).twist hϖ f)) := by ext i j simp only [Basis.smulGL_apply, val_cartanDiag, Basis.twist_apply, Pi.smul_apply, smul_eq_mul] fin_cases i <;> fin_cases j <;> simp rw [← this, Basis.smulGL_toLattice] open Pointwise in lemma pow_smul_range_eq_range_iff {ι : Type*} [Finite ι] [Nonempty ι] {ϖ : R} (hϖ : Irreducible ϖ) (n : ℤ) : ϖ.val ^ n • Set.range ((Algebra.linearMap R K).compLeft ι) = Set.range ((Algebra.linearMap R K).compLeft ι) ↔ n = 0 := by classical refine ⟨fun h ↦ ?_, fun h ↦ by subst h; simp⟩ let i : ι := ‹Nonempty ι›.some by_cases hn : n ≥ 0 · rw [Set.ext_iff] at h have : (Pi.basisFun K ι) i ∈ ϖ.val ^ n • Set.range ⇑((Algebra.linearMap (↥R) K).compLeft ι) := by rw [h] use Pi.basisFun R ι i ext simp [Algebra.algebraMap_ofSubring_apply, Pi.single_apply] simp at this rw [Set.mem_smul_set] at this obtain ⟨-, ⟨z, rfl⟩, hy⟩ := this rw [funext_iff] at hy have := hy i simp [Algebra.algebraMap_ofSubring_apply] at this have heq : (ValuationRing.valuation R K) (z i).val = 1 := by rw [← valuation_eq_one_iff, isUnit_iff_exists_inv'] use ⟨ϖ.val ^ n, (irreducible_zpow_mem_subring_iff ϖ hϖ n).mpr hn⟩ ext simpa apply_fun (ValuationRing.valuation R K ·) at this simp [-map_zpow₀] at this rw [heq] at this simp [-map_zpow₀] at this rwa [valuation_irreducible_zpow_eq_one_iff _ hϖ] at this · have : Pi.single i (ϖ.val ^ n) ∈ Set.range ((Algebra.linearMap (↥R) K).compLeft ι) := by rw [← h] rw [Set.mem_smul_set] refine ⟨Pi.single i 1, ?_, ?_⟩ use Pi.single i 1 ext simp [Algebra.algebraMap_ofSubring_apply, Pi.single_apply] ext j simp [Pi.single_apply] simp at this obtain ⟨z, hz⟩ := this rw [funext_iff] at hz have := hz i simp [Algebra.algebraMap_ofSubring_apply] at this have : ϖ.val ^ n ∈ R := by rw [← this] exact (z i).property rw [irreducible_zpow_mem_subring_iff _ hϖ] at this omega open Pointwise in /-- The stabilizer of the standard lattice of the `GL₂(K)`-action on lattices is `GL₂(R)`. -/ lemma stabilizer_standard_eq_range_map_subtype : MulAction.stabilizer (GL (Fin 2) K) (Lattice.standard R) = (Matrix.GeneralLinearGroup.map R.subtype).range := by obtain ⟨ϖ, hϖ⟩ := IsDiscreteValuationRing.exists_irreducible R ext g simp only [MulAction.mem_stabilizer_iff, MonoidHom.mem_range] constructor · intro hg obtain ⟨(k₁ : GL (Fin 2) R), (k₂ : GL (Fin 2) R), (f : Fin 2 → ℤ), hf, h⟩ := cartan_decomposition' (k := 2) ϖ hϖ g rw [← h] at hg erw [mul_smul, GL_map_eq, GL_map_eq, map_subtype_smul_standard_eq_standard k₂, mul_smul] at hg apply_fun (Matrix.GeneralLinearGroup.map R.subtype k₁⁻¹ • ·) at hg simp only [map_inv, PNat.val_ofNat, inv_smul_smul] at hg rw [← map_inv, map_subtype_smul_standard_eq_standard] at hg have hdist : dist (Lattice.standard R) (cartanDiag ϖ hϖ f • Lattice.standard R) = 0 := by simp [hg] simp only [cartanDiag_smul_standard] at hdist simp only [Lattice.standard] at hdist apply_fun Int.ofNat at hdist simp only [Int.ofNat_eq_coe, dist_twist _ _ hf, Fin.isValue, CharP.cast_eq_zero, sub_eq_zero] at hdist rw [Lattice.ext_iff, Lattice.smul_M] at hg simp only [cartanDiag] at hg rw [Matrix.GeneralLinearGroup.diagonal_smul _ _ _ 0] at hg · simp only [Fin.isValue, zpow_neg, Units.smul_mk_apply] at hg have : ϖ.val ^ f 0 • (Lattice.standard R).M = (Lattice.standard R).M := hg rw [Lattice.standard_M, SetLike.ext'_iff] at this simp only [Fin.isValue, Submodule.coe_pointwise_smul, LinearMap.range_coe, pow_smul_range_eq_range_iff hϖ] at this have : f = 0 := by ext i fin_cases i · simpa · simpa [← hdist] subst this use k₁ * k₂ rw [cartanDiag_zero, GL_map_eq, GL_map_eq] at h simpa using h · intro i j fin_cases i <;> fin_cases j <;> simp [hdist] · rintro ⟨k, rfl⟩ rw [map_subtype_smul_standard_eq_standard] open Pointwise in /-- The stabilizer of the `GL₂(K)`-action on the standard vertex is `Kˣ * GL₂(R)`. -/ lemma stabilizer_mk_standard_eq_sup : MulAction.stabilizer (GL (Fin 2) K) (Vertices.mk <| Lattice.standard R) = (Matrix.GeneralLinearGroup.embDiagonal K (Fin 2)).range ⊔ (Matrix.GeneralLinearGroup.map (n := Fin 2) R.subtype).range := by apply le_antisymm · intro g (hg : ⟦g • Lattice.standard R⟧ = ⟦Lattice.standard R⟧) simp only [Quotient.eq] at hg obtain ⟨u, hu⟩ := hg have (L : Lattice R) : u • L = Matrix.GeneralLinearGroup.embDiagonal _ (Fin 2) u • L := by simp only [Matrix.GeneralLinearGroup.embDiagonal_apply] ext : 1 rw [Lattice.smul_M, Matrix.GeneralLinearGroup.diagonal_smul _ _ _ 1] rfl tauto rw [this, ← mul_smul] at hu have : ((Matrix.GeneralLinearGroup.embDiagonal K (Fin 2)) u * g) ∈ MulAction.stabilizer (GL (Fin 2) K) (Lattice.standard R) := hu rw [stabilizer_standard_eq_range_map_subtype] at this obtain ⟨a, ha⟩ := this have : g = ((Matrix.GeneralLinearGroup.embDiagonal K (Fin 2)) u)⁻¹ * (Matrix.GeneralLinearGroup.map R.subtype) a := by simp [ha] rw [this] apply Subgroup.mul_mem_sup apply Subgroup.inv_mem use u use a · rw [sup_le_iff] constructor · rintro - ⟨u, rfl⟩ simp only [Matrix.GeneralLinearGroup.embDiagonal_apply, MulAction.mem_stabilizer_iff] show ⟦_⟧ = _ have : (Matrix.GL.diagonal fun x : Fin 2 ↦ u) • Lattice.standard R = u • Lattice.standard R := by ext : 1 rw [Lattice.smul_M, Matrix.GeneralLinearGroup.diagonal_smul _ _ _ 1] rfl tauto simp only [this, Quotient.eq] apply Lattice.smul_isSimilar · rintro - ⟨a, rfl⟩ simp only [MulAction.mem_stabilizer_iff] show ⟦_⟧ = _ rw [map_subtype_smul_standard_eq_standard]