l3lab/ntp-mathlib huggingface dataset:
@[simp] lemma birkhoffFinset_sup (a b : α) :
    birkhoffFinset α (a ⊔ b) = birkhoffFinset α a ∪ birkhoffFinset α b := by
  dsimp [OrderEmbedding.birkhoffFinset]
  

Proof state:
α : Type u_1
inst✝³ : DistribLattice α
inst✝² : Fintype α
inst✝¹ : DecidablePred SupIrred
inst✝ : DecidableEq α
a b : α
⊢ (OrderIso.toOrderEmbedding (OrderIso.symm Fintype.finsetOrderIsoSet)) ((birkhoffSet α) (a ⊔ b)) =
    (OrderIso.toOrderEmbedding (OrderIso.symm Fintype.finsetOrderIsoSet)) ((birkhoffSet α) a) ∪
      (OrderIso.toOrderEmbedding (OrderIso.symm Fintype.finsetOrderIsoSet)) ((birkhoffSet α) b)

Next tactic:
rw [birkhoffSet_sup, OrderIso.coe_toOrderEmbedding]
@[simp] lemma birkhoffFinset_sup (a b : α) :
    birkhoffFinset α (a ⊔ b) = birkhoffFinset α a ∪ birkhoffFinset α b := by
  dsimp [OrderEmbedding.birkhoffFinset]
  rw [birkhoffSet_sup, OrderIso.coe_toOrderEmbedding]
  

Proof state:
α : Type u_1
inst✝³ : DistribLattice α
inst✝² : Fintype α
inst✝¹ : DecidablePred SupIrred
inst✝ : DecidableEq α
a b : α
⊢ (OrderIso.symm Fintype.finsetOrderIsoSet) ((birkhoffSet α) a ∪ (birkhoffSet α) b) =
    (OrderIso.symm Fintype.finsetOrderIsoSet) ((birkhoffSet α) a) ∪
      (OrderIso.symm Fintype.finsetOrderIsoSet) ((birkhoffSet α) b)

Next tactic:
simpa using OrderIso.map_sup _ _ _
@[simp] lemma birkhoffFinset_inf (a b : α) :
    birkhoffFinset α (a ⊓ b) = birkhoffFinset α a ∩ birkhoffFinset α b := by
  

Proof state:
α : Type u_1
inst✝³ : DistribLattice α
inst✝² : Fintype α
inst✝¹ : DecidablePred SupIrred
inst✝ : DecidableEq α
a b : α
⊢ (birkhoffFinset α) (a ⊓ b) = (birkhoffFinset α) a ∩ (birkhoffFinset α) b

Next tactic:
dsimp [OrderEmbedding.birkhoffFinset]
@[simp] lemma birkhoffFinset_inf (a b : α) :
    birkhoffFinset α (a ⊓ b) = birkhoffFinset α a ∩ birkhoffFinset α b := by
  dsimp [OrderEmbedding.birkhoffFinset]
  

Proof state:
α : Type u_1
inst✝³ : DistribLattice α
inst✝² : Fintype α
inst✝¹ : DecidablePred SupIrred
inst✝ : DecidableEq α
a b : α
⊢ (OrderIso.toOrderEmbedding (OrderIso.symm Fintype.finsetOrderIsoSet)) ((birkhoffSet α) (a ⊓ b)) =
    (OrderIso.toOrderEmbedding (OrderIso.symm Fintype.finsetOrderIsoSet)) ((birkhoffSet α) a) ∩
      (OrderIso.toOrderEmbedding (OrderIso.symm Fintype.finsetOrderIsoSet)) ((birkhoffSet α) b)

Next tactic:
rw [birkhoffSet_inf, OrderIso.coe_toOrderEmbedding]
@[simp] lemma birkhoffFinset_inf (a b : α) :
    birkhoffFinset α (a ⊓ b) = birkhoffFinset α a ∩ birkhoffFinset α b := by
  dsimp [OrderEmbedding.birkhoffFinset]
  rw [birkhoffSet_inf, OrderIso.coe_toOrderEmbedding]
  

Proof state:
α : Type u_1
inst✝³ : DistribLattice α
inst✝² : Fintype α
inst✝¹ : DecidablePred SupIrred
inst✝ : DecidableEq α
a b : α
⊢ (OrderIso.symm Fintype.finsetOrderIsoSet) ((birkhoffSet α) a ∩ (birkhoffSet α) b) =
    (OrderIso.symm Fintype.finsetOrderIsoSet) ((birkhoffSet α) a) ∩
      (OrderIso.symm Fintype.finsetOrderIsoSet) ((birkhoffSet α) b)

Next tactic:
simpa using OrderIso.map_inf _ _ _
@[simp] lemma birkhoffSet_apply (a : α) : birkhoffSet α a = OrderIso.lowerSetSupIrred a := by
  

Proof state:
α : Type u_1
inst✝⁴ : DistribLattice α
inst✝³ : Fintype α
inst✝² : DecidablePred SupIrred
inst✝¹ : DecidableEq α
inst✝ : OrderBot α
a : α
⊢ (birkhoffSet α) a = ↑(OrderIso.lowerSetSupIrred a)

Next tactic:
simp [birkhoffSet]
@[simp] lemma birkhoffSet_apply (a : α) : birkhoffSet α a = OrderIso.lowerSetSupIrred a := by
  simp [birkhoffSet]; 

Proof state:
α : Type u_1
inst✝⁴ : DistribLattice α
inst✝³ : Fintype α
inst✝² : DecidablePred SupIrred
inst✝¹ : DecidableEq α
inst✝ : OrderBot α
a : α
⊢ OrderIso.lowerSetSupIrred a = OrderIso.lowerSetSupIrred a

Next tactic:
convert rfl
lemma exists_birkhoff_representation.{u} (α : Type u) [Finite α] [DistribLattice α] :
    ∃ (β : Type u) (_ : DecidableEq β) (_ : Fintype β) (f : LatticeHom α (Finset β)),
      Injective f := by
  

Proof state:
α✝ : Type u_1
inst✝² : DistribLattice α✝
α : Type u
inst✝¹ : Finite α
inst✝ : DistribLattice α
⊢ ∃ β x x_1 f, Injective ⇑f

Next tactic:
classical
  cases nonempty_fintype α
  exact ⟨{a : α // SupIrred a}, _ , by infer_instance, _, LatticeHom.birkhoffFinset_injective _⟩
lemma exists_birkhoff_representation.{u} (α : Type u) [Finite α] [DistribLattice α] :
    ∃ (β : Type u) (_ : DecidableEq β) (_ : Fintype β) (f : LatticeHom α (Finset β)),
      Injective f := by
  classical
  

Proof state:
α✝ : Type u_1
inst✝² : DistribLattice α✝
α : Type u
inst✝¹ : Finite α
inst✝ : DistribLattice α
⊢ ∃ β x x_1 f, Injective ⇑f

Next tactic:
cases nonempty_fintype α
lemma exists_birkhoff_representation.{u} (α : Type u) [Finite α] [DistribLattice α] :
    ∃ (β : Type u) (_ : DecidableEq β) (_ : Fintype β) (f : LatticeHom α (Finset β)),
      Injective f := by
  classical
  cases nonempty_fintype α
  

Proof state:
case intro
α✝ : Type u_1
inst✝² : DistribLattice α✝
α : Type u
inst✝¹ : Finite α
inst✝ : DistribLattice α
val✝ : Fintype α
⊢ ∃ β x x_1 f, Injective ⇑f

Next tactic:
exact ⟨{a : α // SupIrred a}, _ , by infer_instance, _, LatticeHom.birkhoffFinset_injective _⟩
lemma exists_birkhoff_representation.{u} (α : Type u) [Finite α] [DistribLattice α] :
    ∃ (β : Type u) (_ : DecidableEq β) (_ : Fintype β) (f : LatticeHom α (Finset β)),
      Injective f := by
  classical
  cases nonempty_fintype α
  exact ⟨{a : α // SupIrred a}, _ , by 

Proof state:
α✝ : Type u_1
inst✝² : DistribLattice α✝
α : Type u
inst✝¹ : Finite α
inst✝ : DistribLattice α
val✝ : Fintype α
⊢ Fintype { a // SupIrred a }

Next tactic:
infer_instance
instance commGroup : CommGroup (G_ab G) where
  mul_comm := fun x y =>
    Quotient.inductionOn₂' x y fun a b =>
      Quotient.sound' <|
        QuotientGroup.leftRel_apply.mpr <| by
          

Proof state:
G : Type u_1
inst✝² : Group G
inst✝¹ : TopologicalSpace G
inst✝ : TopologicalGroup G
src✝ : Group (G_ab G) := inferInstance
x y : G_ab G
a b : G
⊢ ((fun x x_1 => x * x_1) a b)⁻¹ * (fun x x_1 => x * x_1) b a ∈ Subgroup.topologicalClosure (commutator G)

Next tactic:
have h : (a * b)⁻¹ * (b * a) = ⁅b⁻¹, a⁻¹⁆ := by group
instance commGroup : CommGroup (G_ab G) where
  mul_comm := fun x y =>
    Quotient.inductionOn₂' x y fun a b =>
      Quotient.sound' <|
        QuotientGroup.leftRel_apply.mpr <| by
          have h : (a * b)⁻¹ * (b * a) = ⁅b⁻¹, a⁻¹⁆ := by 

Proof state:
G : Type u_1
inst✝² : Group G
inst✝¹ : TopologicalSpace G
inst✝ : TopologicalGroup G
src✝ : Group (G_ab G) := inferInstance
x y : G_ab G
a b : G
⊢ (a * b)⁻¹ * (b * a) = ⁅b⁻¹, a⁻¹⁆

Next tactic:
group
instance commGroup : CommGroup (G_ab G) where
  mul_comm := fun x y =>
    Quotient.inductionOn₂' x y fun a b =>
      Quotient.sound' <|
        QuotientGroup.leftRel_apply.mpr <| by
          have h : (a * b)⁻¹ * (b * a) = ⁅b⁻¹, a⁻¹⁆ := by group
          

Proof state:
G : Type u_1
inst✝² : Group G
inst✝¹ : TopologicalSpace G
inst✝ : TopologicalGroup G
src✝ : Group (G_ab G) := inferInstance
x y : G_ab G
a b : G
h : (a * b)⁻¹ * (b * a) = ⁅b⁻¹, a⁻¹⁆
⊢ ((fun x x_1 => x * x_1) a b)⁻¹ * (fun x x_1 => x * x_1) b a ∈ Subgroup.topologicalClosure (commutator G)

Next tactic:
rw [h]
instance commGroup : CommGroup (G_ab G) where
  mul_comm := fun x y =>
    Quotient.inductionOn₂' x y fun a b =>
      Quotient.sound' <|
        QuotientGroup.leftRel_apply.mpr <| by
          have h : (a * b)⁻¹ * (b * a) = ⁅b⁻¹, a⁻¹⁆ := by group
          rw [h]
          

Proof state:
G : Type u_1
inst✝² : Group G
inst✝¹ : TopologicalSpace G
inst✝ : TopologicalGroup G
src✝ : Group (G_ab G) := inferInstance
x y : G_ab G
a b : G
h : (a * b)⁻¹ * (b * a) = ⁅b⁻¹, a⁻¹⁆
⊢ ⁅b⁻¹, a⁻¹⁆ ∈ Subgroup.topologicalClosure (commutator G)

Next tactic:
exact Subgroup.le_topologicalClosure _ (Subgroup.commutator_mem_commutator
            (Subgroup.mem_top b⁻¹) (Subgroup.mem_top a⁻¹))
theorem dvd_geom_sum₂_iff_of_dvd_sub {x y p : R} (h : p ∣ x - y) :
    (p ∣ ∑ i in range n, x ^ i * y ^ (n - 1 - i)) ↔ p ∣ n * y ^ (n - 1) := by
  

Proof state:
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x✝ y✝ x y p : R
h : p ∣ x - y
⊢ p ∣ ∑ i in range n, x ^ i * y ^ (n - 1 - i) ↔ p ∣ ↑n * y ^ (n - 1)

Next tactic:
rw [← mem_span_singleton, ← Ideal.Quotient.eq] at h
theorem dvd_geom_sum₂_iff_of_dvd_sub {x y p : R} (h : p ∣ x - y) :
    (p ∣ ∑ i in range n, x ^ i * y ^ (n - 1 - i)) ↔ p ∣ n * y ^ (n - 1) := by
  rw [← mem_span_singleton, ← Ideal.Quotient.eq] at h
  

Proof state:
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x✝ y✝ x y p : R
h : (Ideal.Quotient.mk (span {p})) x = (Ideal.Quotient.mk (span {p})) y
⊢ p ∣ ∑ i in range n, x ^ i * y ^ (n - 1 - i) ↔ p ∣ ↑n * y ^ (n - 1)

Next tactic:
simp only [← mem_span_singleton, ← eq_zero_iff_mem, RingHom.map_geom_sum₂, h, geom_sum₂_self,
    _root_.map_mul, map_pow, map_natCast]
theorem dvd_geom_sum₂_iff_of_dvd_sub' {x y p : R} (h : p ∣ x - y) :
    (p ∣ ∑ i in range n, x ^ i * y ^ (n - 1 - i)) ↔ p ∣ n * x ^ (n - 1) := by
  

Proof state:
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x✝ y✝ x y p : R
h : p ∣ x - y
⊢ p ∣ ∑ i in range n, x ^ i * y ^ (n - 1 - i) ↔ p ∣ ↑n * x ^ (n - 1)

Next tactic:
rw [geom_sum₂_comm, dvd_geom_sum₂_iff_of_dvd_sub]
theorem dvd_geom_sum₂_iff_of_dvd_sub' {x y p : R} (h : p ∣ x - y) :
    (p ∣ ∑ i in range n, x ^ i * y ^ (n - 1 - i)) ↔ p ∣ n * x ^ (n - 1) := by
  rw [geom_sum₂_comm, dvd_geom_sum₂_iff_of_dvd_sub]; 

Proof state:
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x✝ y✝ x y p : R
h : p ∣ x - y
⊢ p ∣ y - x

Next tactic:
simpa using h.neg_right
theorem sq_dvd_add_pow_sub_sub (p x : R) (n : ℕ) :
    p ^ 2 ∣ (x + p) ^ n - x ^ (n - 1) * p * n - x ^ n := by
  

Proof state:
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ p ^ 2 ∣ (x + p) ^ n - x ^ (n - 1) * p * ↑n - x ^ n

Next tactic:
cases' n with n n
theorem sq_dvd_add_pow_sub_sub (p x : R) (n : ℕ) :
    p ^ 2 ∣ (x + p) ^ n - x ^ (n - 1) * p * n - x ^ n := by
  cases' n with n n
  · 

Proof state:
case zero
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
⊢ p ^ 2 ∣ (x + p) ^ Nat.zero - x ^ (Nat.zero - 1) * p * ↑Nat.zero - x ^ Nat.zero

Next tactic:
simp only [pow_zero, Nat.cast_zero, sub_zero, sub_self, dvd_zero, Nat.zero_eq, mul_zero]
theorem sq_dvd_add_pow_sub_sub (p x : R) (n : ℕ) :
    p ^ 2 ∣ (x + p) ^ n - x ^ (n - 1) * p * n - x ^ n := by
  cases' n with n n
  · simp only [pow_zero, Nat.cast_zero, sub_zero, sub_self, dvd_zero, Nat.zero_eq, mul_zero]
  · 

Proof state:
case succ
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ p ^ 2 ∣ (x + p) ^ Nat.succ n - x ^ (Nat.succ n - 1) * p * ↑(Nat.succ n) - x ^ Nat.succ n

Next tactic:
simp only [Nat.succ_sub_succ_eq_sub, tsub_zero, Nat.cast_succ, add_pow, Finset.sum_range_succ,
      Nat.choose_self, Nat.succ_sub _, tsub_self, pow_one, Nat.choose_succ_self_right, pow_zero,
      mul_one, Nat.cast_zero, zero_add, Nat.succ_eq_add_one, add_tsub_cancel_left]
theorem sq_dvd_add_pow_sub_sub (p x : R) (n : ℕ) :
    p ^ 2 ∣ (x + p) ^ n - x ^ (n - 1) * p * n - x ^ n := by
  cases' n with n n
  · simp only [pow_zero, Nat.cast_zero, sub_zero, sub_self, dvd_zero, Nat.zero_eq, mul_zero]
  · simp only [Nat.succ_sub_succ_eq_sub, tsub_zero, Nat.cast_succ, add_pow, Finset.sum_range_succ,
      Nat.choose_self, Nat.succ_sub _, tsub_self, pow_one, Nat.choose_succ_self_right, pow_zero,
      mul_one, Nat.cast_zero, zero_add, Nat.succ_eq_add_one, add_tsub_cancel_left]
    

Proof state:
case succ
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ p ^ 2 ∣
    ∑ m in range n, x ^ m * p ^ (n + 1 - m) * ↑(Nat.choose (n + 1) m) + x ^ n * p * (↑n + 1) + x ^ (n + 1) -
        x ^ n * p * (↑n + 1) -
      x ^ (n + 1)

Next tactic:
suffices p ^ 2 ∣ ∑ i : ℕ in range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i) by
      convert this; abel
theorem sq_dvd_add_pow_sub_sub (p x : R) (n : ℕ) :
    p ^ 2 ∣ (x + p) ^ n - x ^ (n - 1) * p * n - x ^ n := by
  cases' n with n n
  · simp only [pow_zero, Nat.cast_zero, sub_zero, sub_self, dvd_zero, Nat.zero_eq, mul_zero]
  · simp only [Nat.succ_sub_succ_eq_sub, tsub_zero, Nat.cast_succ, add_pow, Finset.sum_range_succ,
      Nat.choose_self, Nat.succ_sub _, tsub_self, pow_one, Nat.choose_succ_self_right, pow_zero,
      mul_one, Nat.cast_zero, zero_add, Nat.succ_eq_add_one, add_tsub_cancel_left]
    suffices p ^ 2 ∣ ∑ i : ℕ in range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i) by
      

Proof state:
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
this : p ^ 2 ∣ ∑ i in range n, x ^ i * p ^ (n + 1 - i) * ↑(Nat.choose (n + 1) i)
⊢ p ^ 2 ∣
    ∑ m in range n, x ^ m * p ^ (n + 1 - m) * ↑(Nat.choose (n + 1) m) + x ^ n * p * (↑n + 1) + x ^ (n + 1) -
        x ^ n * p * (↑n + 1) -
      x ^ (n + 1)

Next tactic:
convert this
theorem sq_dvd_add_pow_sub_sub (p x : R) (n : ℕ) :
    p ^ 2 ∣ (x + p) ^ n - x ^ (n - 1) * p * n - x ^ n := by
  cases' n with n n
  · simp only [pow_zero, Nat.cast_zero, sub_zero, sub_self, dvd_zero, Nat.zero_eq, mul_zero]
  · simp only [Nat.succ_sub_succ_eq_sub, tsub_zero, Nat.cast_succ, add_pow, Finset.sum_range_succ,
      Nat.choose_self, Nat.succ_sub _, tsub_self, pow_one, Nat.choose_succ_self_right, pow_zero,
      mul_one, Nat.cast_zero, zero_add, Nat.succ_eq_add_one, add_tsub_cancel_left]
    suffices p ^ 2 ∣ ∑ i : ℕ in range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i) by
      convert this; 

Proof state:
case h.e'_4
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
this : p ^ 2 ∣ ∑ i in range n, x ^ i * p ^ (n + 1 - i) * ↑(Nat.choose (n + 1) i)
⊢ ∑ m in range n, x ^ m * p ^ (n + 1 - m) * ↑(Nat.choose (n + 1) m) + x ^ n * p * (↑n + 1) + x ^ (n + 1) -
        x ^ n * p * (↑n + 1) -
      x ^ (n + 1) =
    ∑ i in range n, x ^ i * p ^ (n + 1 - i) * ↑(Nat.choose (n + 1) i)

Next tactic:
abel
theorem sq_dvd_add_pow_sub_sub (p x : R) (n : ℕ) :
    p ^ 2 ∣ (x + p) ^ n - x ^ (n - 1) * p * n - x ^ n := by
  cases' n with n n
  · simp only [pow_zero, Nat.cast_zero, sub_zero, sub_self, dvd_zero, Nat.zero_eq, mul_zero]
  · simp only [Nat.succ_sub_succ_eq_sub, tsub_zero, Nat.cast_succ, add_pow, Finset.sum_range_succ,
      Nat.choose_self, Nat.succ_sub _, tsub_self, pow_one, Nat.choose_succ_self_right, pow_zero,
      mul_one, Nat.cast_zero, zero_add, Nat.succ_eq_add_one, add_tsub_cancel_left]
    suffices p ^ 2 ∣ ∑ i : ℕ in range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i) by
      convert this; abel
    · 

Proof state:
case succ
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ p ^ 2 ∣ ∑ i in range n, x ^ i * p ^ (n + 1 - i) * ↑(Nat.choose (n + 1) i)

Next tactic:
apply Finset.dvd_sum
theorem sq_dvd_add_pow_sub_sub (p x : R) (n : ℕ) :
    p ^ 2 ∣ (x + p) ^ n - x ^ (n - 1) * p * n - x ^ n := by
  cases' n with n n
  · simp only [pow_zero, Nat.cast_zero, sub_zero, sub_self, dvd_zero, Nat.zero_eq, mul_zero]
  · simp only [Nat.succ_sub_succ_eq_sub, tsub_zero, Nat.cast_succ, add_pow, Finset.sum_range_succ,
      Nat.choose_self, Nat.succ_sub _, tsub_self, pow_one, Nat.choose_succ_self_right, pow_zero,
      mul_one, Nat.cast_zero, zero_add, Nat.succ_eq_add_one, add_tsub_cancel_left]
    suffices p ^ 2 ∣ ∑ i : ℕ in range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i) by
      convert this; abel
    · apply Finset.dvd_sum
      

Proof state:
case succ.h
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y p x : R
n : ℕ
⊢ ∀ x_1 ∈ range n, p ^ 2 ∣ x ^ x_1 * p ^ (n + 1 - x_1) * ↑(Nat.choose (n + 1) x_1)

Next tactic:
intro y hy
theorem sq_dvd_add_pow_sub_sub (p x : R) (n : ℕ) :
    p ^ 2 ∣ (x + p) ^ n - x ^ (n - 1) * p * n - x ^ n := by
  cases' n with n n
  · simp only [pow_zero, Nat.cast_zero, sub_zero, sub_self, dvd_zero, Nat.zero_eq, mul_zero]
  · simp only [Nat.succ_sub_succ_eq_sub, tsub_zero, Nat.cast_succ, add_pow, Finset.sum_range_succ,
      Nat.choose_self, Nat.succ_sub _, tsub_self, pow_one, Nat.choose_succ_self_right, pow_zero,
      mul_one, Nat.cast_zero, zero_add, Nat.succ_eq_add_one, add_tsub_cancel_left]
    suffices p ^ 2 ∣ ∑ i : ℕ in range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i) by
      convert this; abel
    · apply Finset.dvd_sum
      intro y hy
      

Proof state:
case succ.h
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y✝ p x : R
n y : ℕ
hy : y ∈ range n
⊢ p ^ 2 ∣ x ^ y * p ^ (n + 1 - y) * ↑(Nat.choose (n + 1) y)

Next tactic:
calc
        p ^ 2 ∣ p ^ (n + 1 - y) :=
          pow_dvd_pow p (le_tsub_of_add_le_left (by linarith [Finset.mem_range.mp hy]))
        _ ∣ x ^ y * p ^ (n + 1 - y) * ↑((n + 1).choose y) :=
          dvd_mul_of_dvd_left (dvd_mul_left _ _) _
theorem sq_dvd_add_pow_sub_sub (p x : R) (n : ℕ) :
    p ^ 2 ∣ (x + p) ^ n - x ^ (n - 1) * p * n - x ^ n := by
  cases' n with n n
  · simp only [pow_zero, Nat.cast_zero, sub_zero, sub_self, dvd_zero, Nat.zero_eq, mul_zero]
  · simp only [Nat.succ_sub_succ_eq_sub, tsub_zero, Nat.cast_succ, add_pow, Finset.sum_range_succ,
      Nat.choose_self, Nat.succ_sub _, tsub_self, pow_one, Nat.choose_succ_self_right, pow_zero,
      mul_one, Nat.cast_zero, zero_add, Nat.succ_eq_add_one, add_tsub_cancel_left]
    suffices p ^ 2 ∣ ∑ i : ℕ in range n, x ^ i * p ^ (n + 1 - i) * ↑((n + 1).choose i) by
      convert this; abel
    · apply Finset.dvd_sum
      intro y hy
      calc
        p ^ 2 ∣ p ^ (n + 1 - y) :=
          pow_dvd_pow p (le_tsub_of_add_le_left (by 

Proof state:
R : Type u_1
n✝ : ℕ
inst✝ : CommRing R
a b x✝ y✝ p x : R
n y : ℕ
hy : y ∈ range n
⊢ y + 2 ≤ n + 1

Next tactic:
linarith [Finset.mem_range.mp hy]
theorem odd_sq_dvd_geom_sum₂_sub (hp : Odd p) :
    (p : R) ^ 2 ∣ (∑ i in range p, (a + p * b) ^ i * a ^ (p - 1 - i)) - p * a ^ (p - 1) := by
  

Proof state:
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x y : R
p : ℕ
hp : Odd p
⊢ ↑p ^ 2 ∣ ∑ i in range p, (a + ↑p * b) ^ i * a ^ (p - 1 - i) - ↑p * a ^ (p - 1)

Next tactic:
have h1 : ∀ (i : ℕ),
      (p : R) ^ 2 ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * i + a ^ i) := by
    intro i
    calc
      ↑p ^ 2 ∣ (↑p * b) ^ 2 := by simp only [mul_pow, dvd_mul_right]
      _ ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * ↑i + a ^ i) := by
        simp only [sq_dvd_add_pow_sub_sub (↑p * b) a i, ← sub_sub]
theorem odd_sq_dvd_geom_sum₂_sub (hp : Odd p) :
    (p : R) ^ 2 ∣ (∑ i in range p, (a + p * b) ^ i * a ^ (p - 1 - i)) - p * a ^ (p - 1) := by
  have h1 : ∀ (i : ℕ),
      (p : R) ^ 2 ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * i + a ^ i) := by
    

Proof state:
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x y : R
p : ℕ
hp : Odd p
⊢ ∀ (i : ℕ), ↑p ^ 2 ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * ↑i + a ^ i)

Next tactic:
intro i
theorem odd_sq_dvd_geom_sum₂_sub (hp : Odd p) :
    (p : R) ^ 2 ∣ (∑ i in range p, (a + p * b) ^ i * a ^ (p - 1 - i)) - p * a ^ (p - 1) := by
  have h1 : ∀ (i : ℕ),
      (p : R) ^ 2 ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * i + a ^ i) := by
    intro i
    

Proof state:
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x y : R
p : ℕ
hp : Odd p
i : ℕ
⊢ ↑p ^ 2 ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * ↑i + a ^ i)

Next tactic:
calc
      ↑p ^ 2 ∣ (↑p * b) ^ 2 := by simp only [mul_pow, dvd_mul_right]
      _ ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * ↑i + a ^ i) := by
        simp only [sq_dvd_add_pow_sub_sub (↑p * b) a i, ← sub_sub]
theorem odd_sq_dvd_geom_sum₂_sub (hp : Odd p) :
    (p : R) ^ 2 ∣ (∑ i in range p, (a + p * b) ^ i * a ^ (p - 1 - i)) - p * a ^ (p - 1) := by
  have h1 : ∀ (i : ℕ),
      (p : R) ^ 2 ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * i + a ^ i) := by
    intro i
    calc
      ↑p ^ 2 ∣ (↑p * b) ^ 2 := by 

Proof state:
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x y : R
p : ℕ
hp : Odd p
i : ℕ
⊢ ↑p ^ 2 ∣ (↑p * b) ^ 2

Next tactic:
simp only [mul_pow, dvd_mul_right]
theorem odd_sq_dvd_geom_sum₂_sub (hp : Odd p) :
    (p : R) ^ 2 ∣ (∑ i in range p, (a + p * b) ^ i * a ^ (p - 1 - i)) - p * a ^ (p - 1) := by
  have h1 : ∀ (i : ℕ),
      (p : R) ^ 2 ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * i + a ^ i) := by
    intro i
    calc
      ↑p ^ 2 ∣ (↑p * b) ^ 2 := by simp only [mul_pow, dvd_mul_right]
      _ ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * ↑i + a ^ i) := by
        

Proof state:
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x y : R
p : ℕ
hp : Odd p
i : ℕ
⊢ (↑p * b) ^ 2 ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * ↑i + a ^ i)

Next tactic:
simp only [sq_dvd_add_pow_sub_sub (↑p * b) a i, ← sub_sub]
theorem odd_sq_dvd_geom_sum₂_sub (hp : Odd p) :
    (p : R) ^ 2 ∣ (∑ i in range p, (a + p * b) ^ i * a ^ (p - 1 - i)) - p * a ^ (p - 1) := by
  have h1 : ∀ (i : ℕ),
      (p : R) ^ 2 ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * i + a ^ i) := by
    intro i
    calc
      ↑p ^ 2 ∣ (↑p * b) ^ 2 := by simp only [mul_pow, dvd_mul_right]
      _ ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * ↑i + a ^ i) := by
        simp only [sq_dvd_add_pow_sub_sub (↑p * b) a i, ← sub_sub]
  

Proof state:
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x y : R
p : ℕ
hp : Odd p
h1 : ∀ (i : ℕ), ↑p ^ 2 ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * ↑i + a ^ i)
⊢ ↑p ^ 2 ∣ ∑ i in range p, (a + ↑p * b) ^ i * a ^ (p - 1 - i) - ↑p * a ^ (p - 1)

Next tactic:
simp_rw [← mem_span_singleton, ← Ideal.Quotient.eq] at *
theorem odd_sq_dvd_geom_sum₂_sub (hp : Odd p) :
    (p : R) ^ 2 ∣ (∑ i in range p, (a + p * b) ^ i * a ^ (p - 1 - i)) - p * a ^ (p - 1) := by
  have h1 : ∀ (i : ℕ),
      (p : R) ^ 2 ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * i + a ^ i) := by
    intro i
    calc
      ↑p ^ 2 ∣ (↑p * b) ^ 2 := by simp only [mul_pow, dvd_mul_right]
      _ ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * ↑i + a ^ i) := by
        simp only [sq_dvd_add_pow_sub_sub (↑p * b) a i, ← sub_sub]
  simp_rw [← mem_span_singleton, ← Ideal.Quotient.eq] at *
  

Proof state:
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x y : R
p : ℕ
hp : Odd p
h1 :
  ∀ (i : ℕ),
    (Ideal.Quotient.mk (span {↑p ^ 2})) ((a + ↑p * b) ^ i) =
      (Ideal.Quotient.mk (span {↑p ^ 2})) (a ^ (i - 1) * (↑p * b) * ↑i + a ^ i)
⊢ (Ideal.Quotient.mk (span {↑p ^ 2})) (∑ i in range p, (a + ↑p * b) ^ i * a ^ (p - 1 - i)) =
    (Ideal.Quotient.mk (span {↑p ^ 2})) (↑p * a ^ (p - 1))

Next tactic:
let s : R := (p : R)^2
theorem odd_sq_dvd_geom_sum₂_sub (hp : Odd p) :
    (p : R) ^ 2 ∣ (∑ i in range p, (a + p * b) ^ i * a ^ (p - 1 - i)) - p * a ^ (p - 1) := by
  have h1 : ∀ (i : ℕ),
      (p : R) ^ 2 ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * i + a ^ i) := by
    intro i
    calc
      ↑p ^ 2 ∣ (↑p * b) ^ 2 := by simp only [mul_pow, dvd_mul_right]
      _ ∣ (a + ↑p * b) ^ i - (a ^ (i - 1) * (↑p * b) * ↑i + a ^ i) := by
        simp only [sq_dvd_add_pow_sub_sub (↑p * b) a i, ← sub_sub]
  simp_rw [← mem_span_singleton, ← Ideal.Quotient.eq] at *
  let s : R := (p : R)^2
  calc
    (Ideal.Quotient.mk (span {s})) (∑ i in range p, (a + (p : R) * b) ^ i * a ^ (p - 1 - i)) =
        ∑ i : ℕ in Finset.range p,
        mk (span {s}) ((a ^ (i - 1) * (↑p * b) * ↑i + a ^ i) * a ^ (p - 1 - i)) :=
      by 

Proof state:
R : Type u_1
n : ℕ
inst✝ : CommRing R
a b x y : R
p : ℕ
hp : Odd p
h1 :
  ∀ (i : ℕ),
    (Ideal.Quotient.mk (span {↑p ^ 2})) ((a + ↑p * b) ^ i) =
      (Ideal.Quotient.mk (span {↑p ^ 2})) (a ^ (i - 1) * (↑p * b) * ↑i + a ^ i)
s : R := ↑p ^ 2
⊢ (Ideal.Quotient.mk (span {s})) (∑ i in range p, (a + ↑p * b) ^ i * a ^ (p - 1 - i)) =
    ∑ i in range p, (Ideal.Quotient.mk (span {s})) ((a ^ (i - 1) * (↑p * b) * ↑i + a ^ i) * a ^ (p - 1 - i))

Next tactic:
simp_rw [RingHom.map_geom_sum₂, ← map_pow, h1, ← _root_.map_mul]