Zulip Chat Archive

Stream: new members

Topic: Simplifying hidden function coercion mess


Gareth Ma (Jun 06 2024 at 23:22):

I have the following proof:

import Mathlib.RepresentationTheory.Character
import Mathlib.RingTheory.RootsOfUnity.Basic
/- import Mathlib.RingTheory.SimpleModule -/

open LinearMap Module Submodule Representation FiniteDimensional Function Pointwise CategoryTheory
  MonoidAlgebra

variable {n : β„•} (hn : 1 < n) {π•œ : Type} [Field π•œ] {ΞΆ : π•œ} (hΞΆ : ΞΆ ∈ primitiveRoots n π•œ)

example {k : β„•} : (FGModuleCat.of π•œ π•œ) β†’ (FGModuleCat.of π•œ π•œ) :=
  -- Without the cast rfl it doesn't work, even when marking as (x : π•œ)
  fun x ↦ (cast rfl x : π•œ) * (ΞΆ : π•œ) ^ k

-- this is very weird
theorem aux (f : (FGModuleCat.of π•œ π•œ).obj β†’β‚—[π•œ] (FGModuleCat.of π•œ π•œ).obj) :
    f = (1 : End (FGModuleCat.of π•œ π•œ)) ↔ f.toFun = _root_.id := by
  constructor <;> intro h
  Β· subst h; ext; simp; exact CategoryTheory.id_apply _
  Β· ext; change f.toFun _ = _; rw [h]; rfl

-- what?
@[ext] theorem af (f g : End (FGModuleCat.of π•œ π•œ)) (h : f.toFun = g.toFun) : f = g := by
  cases f; cases g; congr!; simpa using h

lemma zeta_pow_mod_eq {k : β„•} : ΞΆ ^ (k % n) = ΞΆ ^ k := by
  nth_rw 2 [← Nat.mod_add_div k n]
  rw [mem_primitiveRoots (zero_lt_one.trans hn)] at hΞΆ
  rw [pow_add, pow_mul, hΞΆ.pow_eq_one, one_pow, mul_one]

def cyc_rep : FdRep π•œ (Multiplicative (ZMod n)) where
  V := FGModuleCat.of π•œ π•œ
  ρ := by
    refine MonCat.ofHom <| MonoidHom.mk (OneHom.mk ?_ ?_) ?_
    Β· intro k
      refine ⟨⟨fun x ↦ (cast rfl x : π•œ) * ΞΆ ^ k.val, ?_⟩, ?_⟩
      Β· intros; simp [add_mul]
      Β· intros; simp [← mul_assoc]
    Β· have : (1 : Multiplicative (ZMod n)).val = 0 := (ZMod.val_eq_zero _).mpr rfl
      rw [aux]; ext; simp [this]
    Β· -- this proof is disgusting
      intro x y
      ext z
      simp [obj_carrier]
      have : ΞΆ ^ (x * y).val = ΞΆ ^ y.val * ΞΆ ^ x.val := by
        have : x * y = Multiplicative.toAdd x + Multiplicative.toAdd y := by rw [← toAdd_mul]; rfl
        rw [this, mul_comm, @ZMod.val_add _ ⟨by omega⟩, zeta_pow_mod_eq hn h΢, pow_add]
        rfl
      -- I still don't know what this is doing
      rw [LinearMap.mul_apply, this, ← mul_assoc]
      rfl

And this is currently sorry-free, but I feel like I did it the "wrong way", as in there is a lot of weird function coercion steps in the middle in some weird ways, as commented above. If anyone has some extra time can someone try to simplify the proof and/or point out how this could've been better

Gareth Ma (Jun 06 2024 at 23:25):

Also this top example

example {k : β„•} : (FGModuleCat.of π•œ π•œ) β†’ (FGModuleCat.of π•œ π•œ) :=
  -- Without the cast rfl it doesn't work, even when marking as (x : π•œ)
  fun x ↦ (cast rfl x : π•œ) * (ΞΆ : π•œ) ^ k

is very confusing to me, but I can't tell if it's a bug or not

Gareth Ma (Jun 06 2024 at 23:31):

(I have a way shorter definition now, but I still want to use the categorical definition just as demonstration)

def cyc_rep' : Multiplicative (ZMod n) β†’* (π•œ β†’β‚—[π•œ] π•œ) where
  toFun := fun k ↦ {
    toFun := fun x ↦ x * ΞΆ ^ k.val
    map_add' := by intros; simp [add_mul]
    map_smul' := by intros; simp [← mul_assoc]
  }
  map_one' := by ext; simp; convert pow_zero ΞΆ; simp only [ZMod.val_eq_zero]; rfl
  map_mul' := by
    intros x y
    ext
    have : x * y = Multiplicative.toAdd x + Multiplicative.toAdd y := by rw [← toAdd_mul]; rfl
    simp
    rw [this, mul_comm, @ZMod.val_add _ ⟨by omega⟩, zeta_pow_mod_eq hn h΢, pow_add]
    rfl

noncomputable def cyc_rep'' : FdRep π•œ (Multiplicative (ZMod n)) := FdRep.of (cyc_rep' hn hΞΆ)

Kevin Buzzard (Jun 09 2024 at 08:34):

Gareth Ma said:

Also this top example

example {k : β„•} : (FGModuleCat.of π•œ π•œ) β†’ (FGModuleCat.of π•œ π•œ) :=
  -- Without the cast rfl it doesn't work, even when marking as (x : π•œ)
  fun x ↦ (cast rfl x : π•œ) * (ΞΆ : π•œ) ^ k

is very confusing to me, but I can't tell if it's a bug or not

How about

example {k : β„•} : (FGModuleCat.of π•œ π•œ) β†’ (FGModuleCat.of π•œ π•œ) :=
  fun x ↦ (ΞΆ : π•œ) ^ k β€’ x

?

Kevin Buzzard (Jun 09 2024 at 08:38):

-- this is very weird
theorem aux (f : (FGModuleCat.of π•œ π•œ).obj β†’β‚—[π•œ] (FGModuleCat.of π•œ π•œ).obj) :
    f = (1 : End (FGModuleCat.of π•œ π•œ)) ↔ f.toFun = _root_.id := by

I think f.toFun is a code smell, whatever you're trying to do. Use coercions to function.

Gareth Ma (Jun 09 2024 at 08:47):

I can replace it with f.toAddHom = AddHom.id _, is that better?

Gareth Ma (Jun 09 2024 at 08:50):

How about

example {k : β„•} : (FGModuleCat.of π•œ π•œ) β†’ (FGModuleCat.of π•œ π•œ) :=
  fun x ↦ (ΞΆ : π•œ) ^ k β€’ x

Oh! That's why * doesn't work. I changed my proof below but that doesn't shorten the proof

Gareth Ma (Jun 09 2024 at 08:50):

At least it makes more sense

Eric Wieser (Jun 09 2024 at 08:50):

Or write ⇑f = _root_.id

Gareth Ma (Jun 09 2024 at 08:51):

Ahh,. I see

Kevin Buzzard (Jun 09 2024 at 09:07):

Here's my effort to make the fdRep:

import Mathlib.RepresentationTheory.Character
import Mathlib.RingTheory.RootsOfUnity.Basic
/- import Mathlib.RingTheory.SimpleModule -/

open LinearMap Module Submodule Representation FiniteDimensional Function Pointwise CategoryTheory
  MonoidAlgebra

variable {n : β„•} (hn : 1 < n) {π•œ : Type} [Field π•œ] {ΞΆ : π•œ} (hΞΆ : ΞΆ ∈ primitiveRoots n π•œ)

-- this proof should work with just `NeZero n`
lemma zeta_pow_mod_eq {k : β„•} : ΞΆ ^ (k % n) = ΞΆ ^ k := by
  nth_rw 2 [← Nat.mod_add_div k n]
  rw [mem_primitiveRoots (zero_lt_one.trans hn)] at hΞΆ
  rw [pow_add, pow_mul, hΞΆ.pow_eq_one, one_pow, mul_one]

-- and what you really want is ΞΆ ^ a = ΞΆ ^ b ↔ a % n = b % n

-- missing API?
lemma foo (a b : ZMod n) : (a + b).val % n = (a.val + b.val) % n := by
  have : NeZero n := ⟨by omega⟩ -- that should be the assumption
  simp [← ZMod.natCast_eq_natCast_iff']

open Multiplicative in
def Representation.cyc_rep : Representation π•œ (Multiplicative (ZMod n)) π•œ where
  toFun mk := lsmul π•œ π•œ (ΞΆ ^ (toAdd mk).val)
  map_one' := by ext; simp
  map_mul' x y := by
    ext
    simp
    rw [← pow_add, ← zeta_pow_mod_eq hn hΞΆ, foo hn, zeta_pow_mod_eq hn hΞΆ]

noncomputable def cyc_rep :
    FdRep π•œ (Multiplicative (ZMod n)) :=
  FdRep.of (Representation.cyc_rep hn hΞΆ)

Gareth Ma (Jun 09 2024 at 09:17):

Damn, I look back at my original attempt and I have no idea what I'm doing. This is a lot cleaner, thanks

YaΓ«l Dillies (Jun 09 2024 at 09:18):

Are you looking for docs#ZMod.cast_add, Kevin?

Eric Wieser (Jun 09 2024 at 09:34):

I'd split that further and go with

/-- Like `zpowersHom` but for `ZMod` and primitive roots. -/
@[simps]
def zmodpowersHom {ΞΆ : π•œ} (hΞΆ : ΞΆ ∈ primitiveRoots n π•œ) : Multiplicative (ZMod n) β†’* π•œ where
  toFun := fun mk => (ΞΆ ^ mk.toAdd.val)
  map_one' := by simp
  map_mul' := fun x y => by
    simp
    rw [← pow_add, ← zeta_pow_mod_eq hn hΞΆ, foo hn, zeta_pow_mod_eq hn hΞΆ]

open Multiplicative in
def Representation.cyc_rep : Representation π•œ (Multiplicative (ZMod n)) π•œ :=
  (Algebra.lsmul π•œ π•œ π•œ).toMonoidHom.comp (zmodpowersHom hn hΞΆ)

Last updated: May 02 2025 at 03:31 UTC