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

184 lines
7.2 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.GroupAction.Basic
import Mathlib.GroupTheory.Exponent
import Rubin.Tactic
namespace Rubin.Period
variable {G a : Type _}
variable [Group G]
variable [MulAction G α]
-- TODO: move to Rubin.Period
noncomputable def period (p : α) (g : G) : :=
sInf {n : | n > 0 ∧ g ^ n • p = p}
#align period Rubin.Period.period
theorem period_le_fix {p : α} {g : G} {m : } (m_pos : m > 0)
(gmp_eq_p : g ^ m • p = p) : 0 < Rubin.Period.period p g ∧ Rubin.Period.period p g ≤ m :=
by
constructor
· by_contra h'
have period_zero : Rubin.Period.period p g = 0 := by linarith
rcases Nat.sInf_eq_zero.1 period_zero with ⟨cont, _⟩ | h
· linarith
· exact Set.eq_empty_iff_forall_not_mem.mp h ↑m ⟨m_pos, gmp_eq_p⟩
exact Nat.sInf_le ⟨m_pos, gmp_eq_p⟩
#align period_le_fix Rubin.Period.period_le_fix
theorem notfix_le_period {p : α} {g : G} {n : }
(period_pos : Rubin.Period.period p g > 0) (pmoves : ∀ i : , 0 < i → i < n → g ^ i • p ≠ p) :
n ≤ Rubin.Period.period p g := by
by_contra period_le
exact
(pmoves (Rubin.Period.period p g) period_pos (not_le.mp period_le))
(Nat.sInf_mem (Nat.nonempty_of_pos_sInf period_pos)).2
#align notfix_le_period Rubin.Period.notfix_le_period
theorem notfix_le_period' {p : α} {g : G} {n : }
(period_pos : 0 < Rubin.Period.period p g)
(pmoves : ∀ i : Fin n, 0 < (i : ) → g ^ (i : ) • p ≠ p) : n ≤ Rubin.Period.period p g :=
Rubin.Period.notfix_le_period period_pos fun (i : ) (i_pos : 0 < i) (i_lt_n : i < n) =>
pmoves (⟨i, i_lt_n⟩ : Fin n) i_pos
#align notfix_le_period' Rubin.Period.notfix_le_period'
theorem period_neutral_eq_one (p : α) : Rubin.Period.period p (1 : G) = 1 :=
by
have : 0 < Rubin.Period.period p (1 : G) ∧ Rubin.Period.period p (1 : G) ≤ 1 :=
Rubin.Period.period_le_fix (by norm_num : 1 > 0)
(by group_action :
(1 : G) ^ 1 • p = p)
linarith
#align period_neutral_eq_one Rubin.Period.period_neutral_eq_one
theorem moves_within_period {n : } (g : G) (x : α) :
0 < n → n < period x g → g^n • x ≠ x :=
by
intro n_pos n_lt_period
unfold period at n_lt_period
apply Nat.not_mem_of_lt_sInf at n_lt_period
simp at n_lt_period
apply n_lt_period
exact n_pos
-- Variant of moves_within_period, which works with integers
theorem moves_within_period' {z : } (g : G) (x : α) :
0 < z → z < period x g → g^z • x ≠ x :=
by
intro n_pos n_lt_period
rw [<-Int.natAbs_of_nonneg (Int.le_of_lt n_pos)]
rw [zpow_ofNat]
apply moves_within_period
· rw [<-Int.natAbs_zero]
apply Int.natAbs_lt_natAbs_of_nonneg_of_lt
rfl
assumption
· rw [<-Int.natAbs_cast (period x g)]
apply Int.natAbs_lt_natAbs_of_nonneg_of_lt
exact Int.le_of_lt n_pos
assumption
def periods (U : Set α) (H : Subgroup G) : Set :=
{n : | ∃ (p : α) (g : H), p ∈ U ∧ Rubin.Period.period (p : α) (g : G) = n}
#align periods Rubin.Period.periods
-- TODO: split into multiple lemmas
theorem periods_lemmas {U : Set α} (U_nonempty : Set.Nonempty U) {H : Subgroup G}
(exp_ne_zero : Monoid.exponent H ≠ 0) :
(Rubin.Period.periods U H).Nonempty ∧
BddAbove (Rubin.Period.periods U H) ∧
∃ (m : ), m > 0 ∧ ∀ (p : α) (g : H), g ^ m • p = p :=
by
rcases Monoid.exponentExists_iff_ne_zero.2 exp_ne_zero with ⟨m, m_pos, gm_eq_one⟩
have gmp_eq_p : ∀ (p : α) (g : H), g ^ m • p = p := by
intro p g; rw [gm_eq_one g];
group_action
have periods_nonempty : (Rubin.Period.periods U H).Nonempty := by
use 1
let p := Set.Nonempty.some U_nonempty; use p
use 1
constructor
· exact Set.Nonempty.some_mem U_nonempty
· exact Rubin.Period.period_neutral_eq_one p
have periods_bounded : BddAbove (Rubin.Period.periods U H) := by
use m; intro some_period hperiod;
rcases hperiod with ⟨p, g, hperiod⟩
rw [← hperiod.2]
exact (Rubin.Period.period_le_fix m_pos (gmp_eq_p p g)).2
exact ⟨periods_nonempty, periods_bounded, m, m_pos, gmp_eq_p⟩
#align period_lemma Rubin.Period.periods_lemmas
theorem period_from_exponent (U : Set α) (U_nonempty : U.Nonempty) {H : Subgroup G}
(exp_ne_zero : Monoid.exponent H ≠ 0) :
∃ (p : α) (g : H) (n : ),
p ∈ U ∧ n > 0 ∧ Rubin.Period.period (p : α) (g : G) = n ∧ n = sSup (Rubin.Period.periods U H) :=
by
rcases Rubin.Period.periods_lemmas U_nonempty exp_ne_zero with
⟨periods_nonempty, periods_bounded, m, m_pos, gmp_eq_p⟩
rcases Nat.sSup_mem periods_nonempty periods_bounded with ⟨p, g, hperiod⟩
use p
use g
use sSup (Rubin.Period.periods U H)
-- TODO: cleanup?
exact ⟨
hperiod.1,
hperiod.2 ▸ (Rubin.Period.period_le_fix m_pos (gmp_eq_p p g)).1,
hperiod.2,
rfl
#align period_from_exponent Rubin.Period.period_from_exponent
theorem zero_lt_period_le_Sup_periods {U : Set α} (U_nonempty : U.Nonempty)
{H : Subgroup G} (exp_ne_zero : Monoid.exponent H ≠ 0) :
∀ (p : U) (g : H),
0 < Rubin.Period.period (p : α) (g : G) ∧
Rubin.Period.period (p : α) (g : G) ≤ sSup (Rubin.Period.periods U H) :=
by
rcases Rubin.Period.periods_lemmas U_nonempty exp_ne_zero with
⟨_periods_nonempty, periods_bounded, m, m_pos, gmp_eq_p⟩
intro p g
have period_in_periods : Rubin.Period.period (p : α) (g : G) ∈ Rubin.Period.periods U H := by
use p; use g
simp
exact
⟨(Rubin.Period.period_le_fix m_pos (gmp_eq_p p g)).1,
le_csSup periods_bounded period_in_periods⟩
#align zero_lt_period_le_Sup_periods Rubin.Period.zero_lt_period_le_Sup_periods
theorem period_pos {U : Set α} (U_nonempty : U.Nonempty) {H : Subgroup G}
(exp_ne_zero : Monoid.exponent H ≠ 0) :
∀ (p : U) (g : H), 0 < Rubin.Period.period (p : α) (g : G) :=
fun p g =>
(zero_lt_period_le_Sup_periods U_nonempty exp_ne_zero p g).1
theorem period_pos' {U : Set α} (U_nonempty : U.Nonempty) {H : Subgroup G}
(exp_ne_zero : Monoid.exponent H ≠ 0) :
∀ (p : α) (g : G), p ∈ U → g ∈ H → 0 < Rubin.Period.period (p : α) (g : G) :=
fun p g p_in_U g_in_H => period_pos U_nonempty exp_ne_zero ⟨p, p_in_U⟩ ⟨g, g_in_H⟩
theorem period_le_Sup_periods {U : Set α} (U_nonempty : U.Nonempty)
{H : Subgroup G} (exp_ne_zero : Monoid.exponent H ≠ 0) :
∀ (p : U) (g : H), Rubin.Period.period (p : α) (g : G) ≤ sSup (Rubin.Period.periods U H) :=
fun p g =>
(zero_lt_period_le_Sup_periods U_nonempty exp_ne_zero p g).2
theorem period_le_Sup_periods' {U : Set α} (U_nonempty : U.Nonempty)
{H : Subgroup G} (exp_ne_zero : Monoid.exponent H ≠ 0) :
∀ (p : α) (g : G), p ∈ U → g ∈ H → Rubin.Period.period p g ≤ sSup (Rubin.Period.periods U H) :=
fun p g p_in_U g_in_H => period_le_Sup_periods U_nonempty exp_ne_zero ⟨p, p_in_U⟩ ⟨g, g_in_H⟩
-- TODO: rename to pow_period_fixes
theorem pow_period_fix (p : α) (g : G) : g ^ Rubin.Period.period p g • p = p := by
cases eq_zero_or_neZero (Rubin.Period.period p g) with
| inl h => rw [h]; simp
| inr h =>
exact
(Nat.sInf_mem
(Nat.nonempty_of_pos_sInf
(Nat.pos_of_ne_zero (@NeZero.ne _ _ (Rubin.Period.period p g) h)))).2
#align pow_period_fix Rubin.Period.pow_period_fix
end Rubin.Period