Theorem: sum_hom_units_eq_zero
File: Mathlib/RingTheory/IntegralDomain.lean

tactic: obtain ⟨x, hx⟩ : ∃ x : MonoidHom.range f.toHomUnits,
    ∀ y : MonoidHom.range f.toHomUnits, y ∈ Submonoid.powers x :=
  IsCyclic.exists_monoid_generator
state_before: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
⊢ ∑ g : G, f g = 0
state_after: case intro
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
⊢ ∑ g : G, f g = 0

tactic: have hx1 : x ≠ 1 := by
  rintro rfl
  apply hf
  ext g
  rw [MonoidHom.one_apply]
  cases' hx ⟨f.toHomUnits g, g, rfl⟩ with n hn
  rwa [Subtype.ext_iff, Units.ext_iff, Subtype.coe_mk, MonoidHom.coe_toHomUnits, one_pow,
    eq_comm] at hn
state_before: case intro
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
⊢ ∑ g : G, f g = 0
state_after: case intro
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : x ≠ 1
⊢ ∑ g : G, f g = 0

tactic: replace hx1 : (x.val : R) - 1 ≠ 0 := fun h => hx1 (Subtype.eq (Units.ext (sub_eq_zero.1 h)))
state_before: case intro
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : x ≠ 1
⊢ ∑ g : G, f g = 0
state_after: case intro
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
⊢ ∑ g : G, f g = 0

tactic: let c := (univ.filter fun g => f.toHomUnits g = 1).card
state_before: case intro
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
⊢ ∑ g : G, f g = 0
state_after: case intro
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
⊢ ∑ g : G, f g = 0

tactic: calc
  ∑ g : G, f g = ∑ g : G, (f.toHomUnits g : R) := rfl
  _ = ∑ u ∈ univ.image f.toHomUnits,
        (univ.filter fun g => f.toHomUnits g = u).card • (u : R) :=
    (sum_comp ((↑) : Rˣ → R) f.toHomUnits)
  _ = ∑ u ∈ univ.image f.toHomUnits, c • (u : R) :=
    (sum_congr rfl fun u hu => congr_arg₂ _ ?_ rfl)
  _ = ∑ b : MonoidHom.range f.toHomUnits, c • ((b : Rˣ) : R) :=
    (Finset.sum_subtype _ (by simp) _)
  _ = c • ∑ b : MonoidHom.range f.toHomUnits, ((b : Rˣ) : R) := smul_sum.symm
  _ = c • (0 : R) := congr_arg₂ _ rfl ?_
  _ = (0 : R) := smul_zero _
state_before: case intro
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
⊢ ∑ g : G, f g = 0
state_after: case intro.calc_1
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
u : Rˣ
hu : u ∈ image (⇑f.toHomUnits) univ
⊢ (filter (fun g => f.toHomUnits g = u) univ).card = c

case intro.calc_2
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
⊢ ∑ b : ↥f.toHomUnits.range, ↑↑b = 0

tactic: rw [← mul_left_inj' hx1, zero_mul, geom_sum_mul]
state_before: case intro.calc_2
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
⊢ ∑ n ∈ range (orderOf x), ↑↑x ^ n = 0
state_after: case intro.calc_2
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
⊢ ↑↑x ^ orderOf x - 1 = 0

tactic: norm_cast
state_before: case intro.calc_2
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
⊢ ↑↑x ^ orderOf x - 1 = 0
state_after: case intro.calc_2
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
⊢ ↑↑(x ^ orderOf x) - 1 = 0

tactic: simp [pow_orderOf_eq_one]
state_before: case intro.calc_2
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
⊢ ↑↑(x ^ orderOf x) - 1 = 0
state_after: no goals

tactic: rintro rfl
state_before: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
⊢ x ≠ 1
state_after: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers 1
⊢ False

tactic: apply hf
state_before: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers 1
⊢ False
state_after: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers 1
⊢ f = 1

tactic: ext g
state_before: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers 1
⊢ f = 1
state_after: case h
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers 1
g : G
⊢ f g = 1 g

tactic: rw [MonoidHom.one_apply]
state_before: case h
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers 1
g : G
⊢ f g = 1 g
state_after: case h
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers 1
g : G
⊢ f g = 1

tactic: cases' hx ⟨f.toHomUnits g, g, rfl⟩ with n hn
state_before: case h
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers 1
g : G
⊢ f g = 1
state_after: case h.intro
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers 1
g : G
n : ℕ
hn : (fun x => 1 ^ x) n = ⟨f.toHomUnits g, ⋯⟩
⊢ f g = 1

tactic: rwa [Subtype.ext_iff, Units.ext_iff, Subtype.coe_mk, MonoidHom.coe_toHomUnits, one_pow,
  eq_comm] at hn
state_before: case h.intro
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers 1
g : G
n : ℕ
hn : (fun x => 1 ^ x) n = ⟨f.toHomUnits g, ⋯⟩
⊢ f g = 1
state_after: no goals

tactic: simp
state_before: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
⊢ ∀ (x : Rˣ), x ∈ image (⇑f.toHomUnits) univ ↔ x ∈ f.toHomUnits.range
state_after: no goals

tactic: apply MonoidHom.card_fiber_eq_of_mem_range f.toHomUnits
state_before: case intro.calc_1
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
u : Rˣ
hu : u ∈ image (⇑f.toHomUnits) univ
⊢ (filter (fun g => f.toHomUnits g = u) univ).card = c
state_after: case intro.calc_1.hx
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
u : Rˣ
hu : u ∈ image (⇑f.toHomUnits) univ
⊢ u ∈ Set.range ⇑f.toHomUnits

case intro.calc_1.hy
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
u : Rˣ
hu : u ∈ image (⇑f.toHomUnits) univ
⊢ 1 ∈ Set.range ⇑f.toHomUnits

tactic: simpa only [mem_image, mem_univ, true_and, Set.mem_range] using hu
state_before: case intro.calc_1.hx
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
u : Rˣ
hu : u ∈ image (⇑f.toHomUnits) univ
⊢ u ∈ Set.range ⇑f.toHomUnits
state_after: no goals

tactic: exact ⟨1, f.toHomUnits.map_one⟩
state_before: case intro.calc_1.hy
R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
u : Rˣ
hu : u ∈ image (⇑f.toHomUnits) univ
⊢ 1 ∈ Set.range ⇑f.toHomUnits
state_after: no goals

tactic: simp only [mem_univ, forall_true_iff]
state_before: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
⊢ ∀ a ∈ range (orderOf x), (fun x_1 => x ^ x_1) a ∈ univ
state_after: no goals

tactic: simpa using pow_injOn_Iio_orderOf
state_before: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
⊢ Set.InjOn (fun x_1 => x ^ x_1) ↑(range (orderOf x))
state_after: no goals

tactic: dsimp at hn ⊢
state_before: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
b : ↥f.toHomUnits.range
x✝ : b ∈ ↑univ
n : ℕ
hn : (fun x_1 => x ^ x_1) n = b
⊢ (fun x_1 => x ^ x_1) (n % orderOf x) = b
state_after: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
b : ↥f.toHomUnits.range
x✝ : b ∈ ↑univ
n : ℕ
hn : x ^ n = b
⊢ x ^ (n % orderOf x) = b

tactic: rw [pow_mod_orderOf, hn]
state_before: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
b : ↥f.toHomUnits.range
x✝ : b ∈ ↑univ
n : ℕ
hn : x ^ n = b
⊢ x ^ (n % orderOf x) = b
state_after: no goals

tactic: simp only [imp_true_iff, eq_self_iff_true, Subgroup.coe_pow,
Units.val_pow_eq_pow_val]
state_before: R : Type u_1
G : Type u_2
inst✝³ : CommRing R
inst✝² : IsDomain R
inst✝¹ : Group G
inst✝ : Fintype G
f : G →* R
hf : f ≠ 1
x : ↥f.toHomUnits.range
hx : ∀ (y : ↥f.toHomUnits.range), y ∈ Submonoid.powers x
hx1 : ↑↑x - 1 ≠ 0
c : ℕ := (filter (fun g => f.toHomUnits g = 1) univ).card
⊢ ∀ a ∈ range (orderOf x), ↑↑x ^ a = ↑↑((fun x_1 => x ^ x_1) a)
state_after: no goals