l3lab/ntp-mathlib huggingface dataset:
/-- An auxiliary result en route to `ModularGroup.eq_smul_self_of_mem_fdo_mem_fdo`. -/
theorem c_eq_zero (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : (↑ₘg) 1 0 = 0 := by
  have hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → (↑ₘg') 1 0 ≠ 1 := by
    intro g' hg'
    by_contra hc
    let a := (↑ₘg') 0 0
    let d := (↑ₘg') 1 1
    have had : T ^ (-a) * g' = S * T ^ d := by rw [g_eq_of_c_eq_one hc]; group
    let w := T ^ (-a) • g' • z
    have h₁ : w = S • T ^ d • z := by simp only [← mul_smul, had]
    replace h₁ : normSq w < 1 := h₁.symm ▸ normSq_S_smul_lt_one (one_lt_normSq_T_zpow_smul hz d)
    have h₂ : 1 < normSq w := one_lt_normSq_T_zpow_smul hg' (-a)
    linarith
  have hn : (↑ₘg) 1 0 ≠ -1 := by
    intro hc
    

Proof state:
g : SL(2, ℤ)
z : ℍ
hz : z ∈ 𝒟ᵒ
hg : g • z ∈ 𝒟ᵒ
hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → ↑g' 1 0 ≠ 1
hc : ↑g 1 0 = -1
⊢ False

Next tactic:
replace hc : (↑ₘ(-g)) 1 0 = 1
/-- An auxiliary result en route to `ModularGroup.eq_smul_self_of_mem_fdo_mem_fdo`. -/
theorem c_eq_zero (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : (↑ₘg) 1 0 = 0 := by
  have hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → (↑ₘg') 1 0 ≠ 1 := by
    intro g' hg'
    by_contra hc
    let a := (↑ₘg') 0 0
    let d := (↑ₘg') 1 1
    have had : T ^ (-a) * g' = S * T ^ d := by rw [g_eq_of_c_eq_one hc]; group
    let w := T ^ (-a) • g' • z
    have h₁ : w = S • T ^ d • z := by simp only [← mul_smul, had]
    replace h₁ : normSq w < 1 := h₁.symm ▸ normSq_S_smul_lt_one (one_lt_normSq_T_zpow_smul hz d)
    have h₂ : 1 < normSq w := one_lt_normSq_T_zpow_smul hg' (-a)
    linarith
  have hn : (↑ₘg) 1 0 ≠ -1 := by
    intro hc
    replace hc : (↑ₘ(-g)) 1 0 = 1; · 

Proof state:
case hc
g : SL(2, ℤ)
z : ℍ
hz : z ∈ 𝒟ᵒ
hg : g • z ∈ 𝒟ᵒ
hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → ↑g' 1 0 ≠ 1
hc : ↑g 1 0 = -1
⊢ (-↑g) 1 0 = 1

Next tactic:
simp [← neg_eq_iff_eq_neg.mpr hc]
/-- An auxiliary result en route to `ModularGroup.eq_smul_self_of_mem_fdo_mem_fdo`. -/
theorem c_eq_zero (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : (↑ₘg) 1 0 = 0 := by
  have hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → (↑ₘg') 1 0 ≠ 1 := by
    intro g' hg'
    by_contra hc
    let a := (↑ₘg') 0 0
    let d := (↑ₘg') 1 1
    have had : T ^ (-a) * g' = S * T ^ d := by rw [g_eq_of_c_eq_one hc]; group
    let w := T ^ (-a) • g' • z
    have h₁ : w = S • T ^ d • z := by simp only [← mul_smul, had]
    replace h₁ : normSq w < 1 := h₁.symm ▸ normSq_S_smul_lt_one (one_lt_normSq_T_zpow_smul hz d)
    have h₂ : 1 < normSq w := one_lt_normSq_T_zpow_smul hg' (-a)
    linarith
  have hn : (↑ₘg) 1 0 ≠ -1 := by
    intro hc
    replace hc : (↑ₘ(-g)) 1 0 = 1; · simp [← neg_eq_iff_eq_neg.mpr hc]
    

Proof state:
g : SL(2, ℤ)
z : ℍ
hz : z ∈ 𝒟ᵒ
hg : g • z ∈ 𝒟ᵒ
hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → ↑g' 1 0 ≠ 1
hc : (-↑g) 1 0 = 1
⊢ False

Next tactic:
replace hg : -g • z ∈ 𝒟ᵒ := (SL_neg_smul g z).symm ▸ hg
/-- An auxiliary result en route to `ModularGroup.eq_smul_self_of_mem_fdo_mem_fdo`. -/
theorem c_eq_zero (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : (↑ₘg) 1 0 = 0 := by
  have hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → (↑ₘg') 1 0 ≠ 1 := by
    intro g' hg'
    by_contra hc
    let a := (↑ₘg') 0 0
    let d := (↑ₘg') 1 1
    have had : T ^ (-a) * g' = S * T ^ d := by rw [g_eq_of_c_eq_one hc]; group
    let w := T ^ (-a) • g' • z
    have h₁ : w = S • T ^ d • z := by simp only [← mul_smul, had]
    replace h₁ : normSq w < 1 := h₁.symm ▸ normSq_S_smul_lt_one (one_lt_normSq_T_zpow_smul hz d)
    have h₂ : 1 < normSq w := one_lt_normSq_T_zpow_smul hg' (-a)
    linarith
  have hn : (↑ₘg) 1 0 ≠ -1 := by
    intro hc
    replace hc : (↑ₘ(-g)) 1 0 = 1; · simp [← neg_eq_iff_eq_neg.mpr hc]
    replace hg : -g • z ∈ 𝒟ᵒ := (SL_neg_smul g z).symm ▸ hg
    

Proof state:
g : SL(2, ℤ)
z : ℍ
hz : z ∈ 𝒟ᵒ
hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → ↑g' 1 0 ≠ 1
hc : (-↑g) 1 0 = 1
hg : -g • z ∈ 𝒟ᵒ
⊢ False

Next tactic:
exact hp hg hc
/-- An auxiliary result en route to `ModularGroup.eq_smul_self_of_mem_fdo_mem_fdo`. -/
theorem c_eq_zero (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : (↑ₘg) 1 0 = 0 := by
  have hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → (↑ₘg') 1 0 ≠ 1 := by
    intro g' hg'
    by_contra hc
    let a := (↑ₘg') 0 0
    let d := (↑ₘg') 1 1
    have had : T ^ (-a) * g' = S * T ^ d := by rw [g_eq_of_c_eq_one hc]; group
    let w := T ^ (-a) • g' • z
    have h₁ : w = S • T ^ d • z := by simp only [← mul_smul, had]
    replace h₁ : normSq w < 1 := h₁.symm ▸ normSq_S_smul_lt_one (one_lt_normSq_T_zpow_smul hz d)
    have h₂ : 1 < normSq w := one_lt_normSq_T_zpow_smul hg' (-a)
    linarith
  have hn : (↑ₘg) 1 0 ≠ -1 := by
    intro hc
    replace hc : (↑ₘ(-g)) 1 0 = 1; · simp [← neg_eq_iff_eq_neg.mpr hc]
    replace hg : -g • z ∈ 𝒟ᵒ := (SL_neg_smul g z).symm ▸ hg
    exact hp hg hc
  

Proof state:
g : SL(2, ℤ)
z : ℍ
hz : z ∈ 𝒟ᵒ
hg : g • z ∈ 𝒟ᵒ
hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → ↑g' 1 0 ≠ 1
hn : ↑g 1 0 ≠ -1
⊢ ↑g 1 0 = 0

Next tactic:
specialize hp hg
/-- An auxiliary result en route to `ModularGroup.eq_smul_self_of_mem_fdo_mem_fdo`. -/
theorem c_eq_zero (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : (↑ₘg) 1 0 = 0 := by
  have hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → (↑ₘg') 1 0 ≠ 1 := by
    intro g' hg'
    by_contra hc
    let a := (↑ₘg') 0 0
    let d := (↑ₘg') 1 1
    have had : T ^ (-a) * g' = S * T ^ d := by rw [g_eq_of_c_eq_one hc]; group
    let w := T ^ (-a) • g' • z
    have h₁ : w = S • T ^ d • z := by simp only [← mul_smul, had]
    replace h₁ : normSq w < 1 := h₁.symm ▸ normSq_S_smul_lt_one (one_lt_normSq_T_zpow_smul hz d)
    have h₂ : 1 < normSq w := one_lt_normSq_T_zpow_smul hg' (-a)
    linarith
  have hn : (↑ₘg) 1 0 ≠ -1 := by
    intro hc
    replace hc : (↑ₘ(-g)) 1 0 = 1; · simp [← neg_eq_iff_eq_neg.mpr hc]
    replace hg : -g • z ∈ 𝒟ᵒ := (SL_neg_smul g z).symm ▸ hg
    exact hp hg hc
  specialize hp hg
  

Proof state:
g : SL(2, ℤ)
z : ℍ
hz : z ∈ 𝒟ᵒ
hg : g • z ∈ 𝒟ᵒ
hn : ↑g 1 0 ≠ -1
hp : ↑g 1 0 ≠ 1
⊢ ↑g 1 0 = 0

Next tactic:
rcases Int.abs_le_one_iff.mp <| abs_c_le_one hz hg with ⟨⟩
/-- An auxiliary result en route to `ModularGroup.eq_smul_self_of_mem_fdo_mem_fdo`. -/
theorem c_eq_zero (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : (↑ₘg) 1 0 = 0 := by
  have hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → (↑ₘg') 1 0 ≠ 1 := by
    intro g' hg'
    by_contra hc
    let a := (↑ₘg') 0 0
    let d := (↑ₘg') 1 1
    have had : T ^ (-a) * g' = S * T ^ d := by rw [g_eq_of_c_eq_one hc]; group
    let w := T ^ (-a) • g' • z
    have h₁ : w = S • T ^ d • z := by simp only [← mul_smul, had]
    replace h₁ : normSq w < 1 := h₁.symm ▸ normSq_S_smul_lt_one (one_lt_normSq_T_zpow_smul hz d)
    have h₂ : 1 < normSq w := one_lt_normSq_T_zpow_smul hg' (-a)
    linarith
  have hn : (↑ₘg) 1 0 ≠ -1 := by
    intro hc
    replace hc : (↑ₘ(-g)) 1 0 = 1; · simp [← neg_eq_iff_eq_neg.mpr hc]
    replace hg : -g • z ∈ 𝒟ᵒ := (SL_neg_smul g z).symm ▸ hg
    exact hp hg hc
  specialize hp hg
  rcases Int.abs_le_one_iff.mp <| abs_c_le_one hz hg with ⟨⟩ <;> 

Proof state:
case inl
g : SL(2, ℤ)
z : ℍ
hz : z ∈ 𝒟ᵒ
hg : g • z ∈ 𝒟ᵒ
hn : ↑g 1 0 ≠ -1
hp : ↑g 1 0 ≠ 1
h✝ : ↑g 1 0 = 0
⊢ ↑g 1 0 = 0

Next tactic:
tauto
/-- An auxiliary result en route to `ModularGroup.eq_smul_self_of_mem_fdo_mem_fdo`. -/
theorem c_eq_zero (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : (↑ₘg) 1 0 = 0 := by
  have hp : ∀ {g' : SL(2, ℤ)}, g' • z ∈ 𝒟ᵒ → (↑ₘg') 1 0 ≠ 1 := by
    intro g' hg'
    by_contra hc
    let a := (↑ₘg') 0 0
    let d := (↑ₘg') 1 1
    have had : T ^ (-a) * g' = S * T ^ d := by rw [g_eq_of_c_eq_one hc]; group
    let w := T ^ (-a) • g' • z
    have h₁ : w = S • T ^ d • z := by simp only [← mul_smul, had]
    replace h₁ : normSq w < 1 := h₁.symm ▸ normSq_S_smul_lt_one (one_lt_normSq_T_zpow_smul hz d)
    have h₂ : 1 < normSq w := one_lt_normSq_T_zpow_smul hg' (-a)
    linarith
  have hn : (↑ₘg) 1 0 ≠ -1 := by
    intro hc
    replace hc : (↑ₘ(-g)) 1 0 = 1; · simp [← neg_eq_iff_eq_neg.mpr hc]
    replace hg : -g • z ∈ 𝒟ᵒ := (SL_neg_smul g z).symm ▸ hg
    exact hp hg hc
  specialize hp hg
  rcases Int.abs_le_one_iff.mp <| abs_c_le_one hz hg with ⟨⟩ <;> 

Proof state:
case inr
g : SL(2, ℤ)
z : ℍ
hz : z ∈ 𝒟ᵒ
hg : g • z ∈ 𝒟ᵒ
hn : ↑g 1 0 ≠ -1
hp : ↑g 1 0 ≠ 1
h✝ : ↑g 1 0 = 1 ∨ ↑g 1 0 = -1
⊢ ↑g 1 0 = 0

Next tactic:
tauto
/-- Second Fundamental Domain Lemma: if both `z` and `g • z` are in the open domain `𝒟ᵒ`,
where `z : ℍ` and `g : SL(2,ℤ)`, then `z = g • z`. -/
theorem eq_smul_self_of_mem_fdo_mem_fdo (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : z = g • z := by
  

Proof state:
g : SL(2, ℤ)
z : ℍ
hz : z ∈ 𝒟ᵒ
hg : g • z ∈ 𝒟ᵒ
⊢ z = g • z

Next tactic:
obtain ⟨n, hn⟩ := exists_eq_T_zpow_of_c_eq_zero (c_eq_zero hz hg)
/-- Second Fundamental Domain Lemma: if both `z` and `g • z` are in the open domain `𝒟ᵒ`,
where `z : ℍ` and `g : SL(2,ℤ)`, then `z = g • z`. -/
theorem eq_smul_self_of_mem_fdo_mem_fdo (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : z = g • z := by
  obtain ⟨n, hn⟩ := exists_eq_T_zpow_of_c_eq_zero (c_eq_zero hz hg)
  

Proof state:
case intro
g : SL(2, ℤ)
z : ℍ
hz : z ∈ 𝒟ᵒ
hg : g • z ∈ 𝒟ᵒ
n : ℤ
hn : ∀ (z : ℍ), g • z = T ^ n • z
⊢ z = g • z

Next tactic:
rw [hn] at hg ⊢
/-- Second Fundamental Domain Lemma: if both `z` and `g • z` are in the open domain `𝒟ᵒ`,
where `z : ℍ` and `g : SL(2,ℤ)`, then `z = g • z`. -/
theorem eq_smul_self_of_mem_fdo_mem_fdo (hz : z ∈ 𝒟ᵒ) (hg : g • z ∈ 𝒟ᵒ) : z = g • z := by
  obtain ⟨n, hn⟩ := exists_eq_T_zpow_of_c_eq_zero (c_eq_zero hz hg)
  rw [hn] at hg ⊢
  

Proof state:
case intro
g : SL(2, ℤ)
z : ℍ
hz : z ∈ 𝒟ᵒ
n : ℤ
hg : T ^ n • z ∈ 𝒟ᵒ
hn : ∀ (z : ℍ), g • z = T ^ n • z
⊢ z = T ^ n • z

Next tactic:
simp [eq_zero_of_mem_fdo_of_T_zpow_mem_fdo hz hg, one_smul]
lemma dvd_smul_of_dvd {M : Type*} [SMul M R] [Semigroup R] [SMulCommClass M R R] {x y : R}
    (m : M) (h : x ∣ y) : x ∣ m • y :=
  let ⟨k, hk⟩ := h; ⟨m • k, by 

Proof state:
R : Type u_1
M : Type u_2
inst✝² : SMul M R
inst✝¹ : Semigroup R
inst✝ : SMulCommClass M R R
x y : R
m : M
h : x ∣ y
k : R
hk : y = x * k
⊢ m • y = x * m • k

Next tactic:
rw [mul_smul_comm, ← hk]
lemma pow_dvd_add_pow_of_pow_eq_zero_right (hy : y ^ n = 0) :
    x ^ m ∣ (x + y) ^ p := by
  

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Semiring R
h_comm : Commute x y
hy : y ^ n = 0
⊢ x ^ m ∣ (x + y) ^ p

Next tactic:
rw [h_comm.add_pow']
lemma pow_dvd_add_pow_of_pow_eq_zero_right (hy : y ^ n = 0) :
    x ^ m ∣ (x + y) ^ p := by
  rw [h_comm.add_pow']
  

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Semiring R
h_comm : Commute x y
hy : y ^ n = 0
⊢ x ^ m ∣ Finset.sum (Finset.antidiagonal p) fun m => Nat.choose p m.1 • (x ^ m.1 * y ^ m.2)

Next tactic:
refine Finset.dvd_sum fun ⟨i, j⟩ hij ↦ ?_
lemma pow_dvd_add_pow_of_pow_eq_zero_right (hy : y ^ n = 0) :
    x ^ m ∣ (x + y) ^ p := by
  rw [h_comm.add_pow']
  refine Finset.dvd_sum fun ⟨i, j⟩ hij ↦ ?_
  

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Semiring R
h_comm : Commute x y
hy : y ^ n = 0
x✝ : ℕ × ℕ
i j : ℕ
hij : (i, j) ∈ Finset.antidiagonal p
⊢ x ^ m ∣ Nat.choose p (i, j).1 • (x ^ (i, j).1 * y ^ (i, j).2)

Next tactic:
replace hij : i + j = p := by simpa using hij
lemma pow_dvd_add_pow_of_pow_eq_zero_right (hy : y ^ n = 0) :
    x ^ m ∣ (x + y) ^ p := by
  rw [h_comm.add_pow']
  refine Finset.dvd_sum fun ⟨i, j⟩ hij ↦ ?_
  replace hij : i + j = p := by 

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Semiring R
h_comm : Commute x y
hy : y ^ n = 0
x✝ : ℕ × ℕ
i j : ℕ
hij : (i, j) ∈ Finset.antidiagonal p
⊢ i + j = p

Next tactic:
simpa using hij
lemma pow_dvd_add_pow_of_pow_eq_zero_right (hy : y ^ n = 0) :
    x ^ m ∣ (x + y) ^ p := by
  rw [h_comm.add_pow']
  refine Finset.dvd_sum fun ⟨i, j⟩ hij ↦ ?_
  replace hij : i + j = p := by simpa using hij
  

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Semiring R
h_comm : Commute x y
hy : y ^ n = 0
x✝ : ℕ × ℕ
i j : ℕ
hij : i + j = p
⊢ x ^ m ∣ Nat.choose p (i, j).1 • (x ^ (i, j).1 * y ^ (i, j).2)

Next tactic:
apply dvd_nsmul_of_dvd
lemma pow_dvd_add_pow_of_pow_eq_zero_right (hy : y ^ n = 0) :
    x ^ m ∣ (x + y) ^ p := by
  rw [h_comm.add_pow']
  refine Finset.dvd_sum fun ⟨i, j⟩ hij ↦ ?_
  replace hij : i + j = p := by simpa using hij
  apply dvd_nsmul_of_dvd
  

Proof state:
case h
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Semiring R
h_comm : Commute x y
hy : y ^ n = 0
x✝ : ℕ × ℕ
i j : ℕ
hij : i + j = p
⊢ x ^ m ∣ x ^ (i, j).1 * y ^ (i, j).2

Next tactic:
rcases le_or_lt m i with (hi : m ≤ i) | (hi : i + 1 ≤ m)
lemma pow_dvd_add_pow_of_pow_eq_zero_right (hy : y ^ n = 0) :
    x ^ m ∣ (x + y) ^ p := by
  rw [h_comm.add_pow']
  refine Finset.dvd_sum fun ⟨i, j⟩ hij ↦ ?_
  replace hij : i + j = p := by simpa using hij
  apply dvd_nsmul_of_dvd
  rcases le_or_lt m i with (hi : m ≤ i) | (hi : i + 1 ≤ m)
  · 

Proof state:
case h.inl
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Semiring R
h_comm : Commute x y
hy : y ^ n = 0
x✝ : ℕ × ℕ
i j : ℕ
hij : i + j = p
hi : m ≤ i
⊢ x ^ m ∣ x ^ (i, j).1 * y ^ (i, j).2

Next tactic:
exact dvd_mul_of_dvd_left (pow_dvd_pow x hi) _
lemma pow_dvd_add_pow_of_pow_eq_zero_right (hy : y ^ n = 0) :
    x ^ m ∣ (x + y) ^ p := by
  rw [h_comm.add_pow']
  refine Finset.dvd_sum fun ⟨i, j⟩ hij ↦ ?_
  replace hij : i + j = p := by simpa using hij
  apply dvd_nsmul_of_dvd
  rcases le_or_lt m i with (hi : m ≤ i) | (hi : i + 1 ≤ m)
  · exact dvd_mul_of_dvd_left (pow_dvd_pow x hi) _
  · 

Proof state:
case h.inr
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Semiring R
h_comm : Commute x y
hy : y ^ n = 0
x✝ : ℕ × ℕ
i j : ℕ
hij : i + j = p
hi : i + 1 ≤ m
⊢ x ^ m ∣ x ^ (i, j).1 * y ^ (i, j).2

Next tactic:
simp [pow_eq_zero_of_le (by linarith : n ≤ j) hy]
lemma pow_dvd_add_pow_of_pow_eq_zero_right (hy : y ^ n = 0) :
    x ^ m ∣ (x + y) ^ p := by
  rw [h_comm.add_pow']
  refine Finset.dvd_sum fun ⟨i, j⟩ hij ↦ ?_
  replace hij : i + j = p := by simpa using hij
  apply dvd_nsmul_of_dvd
  rcases le_or_lt m i with (hi : m ≤ i) | (hi : i + 1 ≤ m)
  · exact dvd_mul_of_dvd_left (pow_dvd_pow x hi) _
  · simp [pow_eq_zero_of_le (by 

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Semiring R
h_comm : Commute x y
hy : y ^ n = 0
x✝ : ℕ × ℕ
i j : ℕ
hij : i + j = p
hi : i + 1 ≤ m
⊢ n ≤ j

Next tactic:
linarith
lemma pow_dvd_pow_of_sub_pow_eq_zero (h : (x - y) ^ n = 0) :
    x ^ m ∣ y ^ p := by
  

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Ring R
h_comm : Commute x y
h : (x - y) ^ n = 0
⊢ x ^ m ∣ y ^ p

Next tactic:
rw [← sub_add_cancel y x]
lemma pow_dvd_pow_of_sub_pow_eq_zero (h : (x - y) ^ n = 0) :
    x ^ m ∣ y ^ p := by
  rw [← sub_add_cancel y x]
  

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Ring R
h_comm : Commute x y
h : (x - y) ^ n = 0
⊢ x ^ m ∣ (y - x + x) ^ p

Next tactic:
apply (h_comm.symm.sub_left rfl).pow_dvd_add_pow_of_pow_eq_zero_left hp _
lemma pow_dvd_pow_of_sub_pow_eq_zero (h : (x - y) ^ n = 0) :
    x ^ m ∣ y ^ p := by
  rw [← sub_add_cancel y x]
  apply (h_comm.symm.sub_left rfl).pow_dvd_add_pow_of_pow_eq_zero_left hp _
  

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Ring R
h_comm : Commute x y
h : (x - y) ^ n = 0
⊢ (y - x) ^ n = 0

Next tactic:
rw [← neg_sub x y, neg_pow, h, mul_zero]
lemma pow_dvd_pow_of_add_pow_eq_zero (h : (x + y) ^ n = 0) :
    x ^ m ∣ y ^ p := by
  

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Ring R
h_comm : Commute x y
h : (x + y) ^ n = 0
⊢ x ^ m ∣ y ^ p

Next tactic:
rw [← neg_neg y, neg_pow']
lemma pow_dvd_pow_of_add_pow_eq_zero (h : (x + y) ^ n = 0) :
    x ^ m ∣ y ^ p := by
  rw [← neg_neg y, neg_pow']
  

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Ring R
h_comm : Commute x y
h : (x + y) ^ n = 0
⊢ x ^ m ∣ (-y) ^ p * (-1) ^ p

Next tactic:
apply dvd_mul_of_dvd_left
lemma pow_dvd_pow_of_add_pow_eq_zero (h : (x + y) ^ n = 0) :
    x ^ m ∣ y ^ p := by
  rw [← neg_neg y, neg_pow']
  apply dvd_mul_of_dvd_left
  

Proof state:
case h
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Ring R
h_comm : Commute x y
h : (x + y) ^ n = 0
⊢ x ^ m ∣ (-y) ^ p

Next tactic:
apply h_comm.neg_right.pow_dvd_pow_of_sub_pow_eq_zero hp
lemma pow_dvd_pow_of_add_pow_eq_zero (h : (x + y) ^ n = 0) :
    x ^ m ∣ y ^ p := by
  rw [← neg_neg y, neg_pow']
  apply dvd_mul_of_dvd_left
  apply h_comm.neg_right.pow_dvd_pow_of_sub_pow_eq_zero hp
  

Proof state:
case h
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Ring R
h_comm : Commute x y
h : (x + y) ^ n = 0
⊢ (x - -y) ^ n = 0

Next tactic:
simpa
lemma pow_dvd_sub_pow_of_pow_eq_zero_right (hy : y ^ n = 0) :
    x ^ m ∣ (x - y) ^ p :=
  (sub_right rfl h_comm).pow_dvd_pow_of_sub_pow_eq_zero hp (by 

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Ring R
h_comm : Commute x y
hy : y ^ n = 0
⊢ (x - (x - y)) ^ n = 0

Next tactic:
simpa
lemma pow_dvd_sub_pow_of_pow_eq_zero_left (hx : x ^ n = 0) :
    y ^ m ∣ (x - y) ^ p := by
  

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Ring R
h_comm : Commute x y
hx : x ^ n = 0
⊢ y ^ m ∣ (x - y) ^ p

Next tactic:
rw [← neg_sub y x, neg_pow']
lemma pow_dvd_sub_pow_of_pow_eq_zero_left (hx : x ^ n = 0) :
    y ^ m ∣ (x - y) ^ p := by
  rw [← neg_sub y x, neg_pow']
  

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Ring R
h_comm : Commute x y
hx : x ^ n = 0
⊢ y ^ m ∣ (y - x) ^ p * (-1) ^ p

Next tactic:
apply dvd_mul_of_dvd_left
lemma pow_dvd_sub_pow_of_pow_eq_zero_left (hx : x ^ n = 0) :
    y ^ m ∣ (x - y) ^ p := by
  rw [← neg_sub y x, neg_pow']
  apply dvd_mul_of_dvd_left
  

Proof state:
case h
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Ring R
h_comm : Commute x y
hx : x ^ n = 0
⊢ y ^ m ∣ (y - x) ^ p

Next tactic:
exact h_comm.symm.pow_dvd_sub_pow_of_pow_eq_zero_right hp hx
lemma add_pow_dvd_pow_of_pow_eq_zero_right (hx : x ^ n = 0) :
    (x + y) ^ m ∣ y ^ p :=
  (h_comm.add_left rfl).pow_dvd_pow_of_sub_pow_eq_zero hp (by 

Proof state:
R : Type u_1
x y : R
n m p : ℕ
hp : n + m ≤ p + 1
inst✝ : Ring R
h_comm : Commute x y
hx : x ^ n = 0
⊢ (x + y - y) ^ n = 0

Next tactic:
simpa
/-- If a functor preserves span and cospan, then it preserves images.
-/
@[simps!]
def iso {X Y : A} (f : X ⟶ Y) : image (L.map f) ≅ L.obj (image f) :=
  let aux1 : StrongEpiMonoFactorisation (L.map f) :=
    { I := L.obj (Limits.image f)
      m := L.map <| Limits.image.ι _
      m_mono := preserves_mono_of_preservesLimit _ _
      e := L.map <| factorThruImage _
      e_strong_epi := @strongEpi_of_epi B _ _ _ _ _ (preserves_epi_of_preservesColimit L _)
      fac := by 

Proof state:
A : Type u₁
B : Type u₂
inst✝⁷ : Category.{v₁, u₁} A
inst✝⁶ : Category.{v₂, u₂} B
inst✝⁵ : HasEqualizers A
inst✝⁴ : HasImages A
inst✝³ : StrongEpiCategory B
inst✝² : HasImages B
L : A ⥤ B
inst✝¹ : {X Y Z : A} → (f : X ⟶ Z) → (g : Y ⟶ Z) → PreservesLimit (cospan f g) L
inst✝ : {X Y Z : A} → (f : X ⟶ Y) → (g : X ⟶ Z) → PreservesColimit (span f g) L
X Y : A
f : X ⟶ Y
⊢ L.map (factorThruImage f) ≫ L.map (image.ι f) = L.map f

Next tactic:
rw [← L.map_comp, Limits.image.fac]
@[reassoc]
theorem factorThruImage_comp_hom {X Y : A} (f : X ⟶ Y) :
    factorThruImage (L.map f) ≫ (iso L f).hom = L.map (factorThruImage f) := by 

Proof state:
A : Type u₁
B : Type u₂
inst✝⁷ : Category.{v₁, u₁} A
inst✝⁶ : Category.{v₂, u₂} B
inst✝⁵ : HasEqualizers A
inst✝⁴ : HasImages A
inst✝³ : StrongEpiCategory B
inst✝² : HasImages B
L : A ⥤ B
inst✝¹ : {X Y Z : A} → (f : X ⟶ Z) → (g : Y ⟶ Z) → PreservesLimit (cospan f g) L
inst✝ : {X Y Z : A} → (f : X ⟶ Y) → (g : X ⟶ Z) → PreservesColimit (span f g) L
X Y : A
f : X ⟶ Y
⊢ factorThruImage (L.map f) ≫ (iso L f).hom = L.map (factorThruImage f)

Next tactic:
simp
@[reassoc]
theorem hom_comp_map_image_ι {X Y : A} (f : X ⟶ Y) :
    (iso L f).hom ≫ L.map (image.ι f) = image.ι (L.map f) := by 

Proof state:
A : Type u₁
B : Type u₂
inst✝⁷ : Category.{v₁, u₁} A
inst✝⁶ : Category.{v₂, u₂} B
inst✝⁵ : HasEqualizers A
inst✝⁴ : HasImages A
inst✝³ : StrongEpiCategory B
inst✝² : HasImages B
L : A ⥤ B
inst✝¹ : {X Y Z : A} → (f : X ⟶ Z) → (g : Y ⟶ Z) → PreservesLimit (cospan f g) L
inst✝ : {X Y Z : A} → (f : X ⟶ Y) → (g : X ⟶ Z) → PreservesColimit (span f g) L
X Y : A
f : X ⟶ Y
⊢ (iso L f).hom ≫ L.map (image.ι f) = image.ι (L.map f)

Next tactic:
rw [iso_hom, image.lift_fac]
@[reassoc]
theorem inv_comp_image_ι_map {X Y : A} (f : X ⟶ Y) :
    (iso L f).inv ≫ image.ι (L.map f) = L.map (image.ι f) := by 

Proof state:
A : Type u₁
B : Type u₂
inst✝⁷ : Category.{v₁, u₁} A
inst✝⁶ : Category.{v₂, u₂} B
inst✝⁵ : HasEqualizers A
inst✝⁴ : HasImages A
inst✝³ : StrongEpiCategory B
inst✝² : HasImages B
L : A ⥤ B
inst✝¹ : {X Y Z : A} → (f : X ⟶ Z) → (g : Y ⟶ Z) → PreservesLimit (cospan f g) L
inst✝ : {X Y Z : A} → (f : X ⟶ Y) → (g : X ⟶ Z) → PreservesColimit (span f g) L
X Y : A
f : X ⟶ Y
⊢ (iso L f).inv ≫ image.ι (L.map f) = L.map (image.ι f)

Next tactic:
simp
theorem le_sum_condensed' (hf : ∀ ⦃m n⦄, 0 < m → m ≤ n → f n ≤ f m) (n : ℕ) :
    (∑ k in Ico 1 (2 ^ n), f k) ≤ ∑ k in range n, 2 ^ k • f (2 ^ k) := by
  

Proof state:
M : Type u_1
inst✝ : OrderedAddCommMonoid M
f : ℕ → M
hf : ∀ ⦃m n : ℕ⦄, 0 < m → m ≤ n → f n ≤ f m
n : ℕ
⊢ ∑ k in Ico 1 (2 ^ n), f k ≤ ∑ k in range n, 2 ^ k • f (2 ^ k)

Next tactic:
induction' n with n ihn
theorem le_sum_condensed' (hf : ∀ ⦃m n⦄, 0 < m → m ≤ n → f n ≤ f m) (n : ℕ) :
    (∑ k in Ico 1 (2 ^ n), f k) ≤ ∑ k in range n, 2 ^ k • f (2 ^ k) := by
  induction' n with n ihn
  · 

Proof state:
case zero
M : Type u_1
inst✝ : OrderedAddCommMonoid M
f : ℕ → M
hf : ∀ ⦃m n : ℕ⦄, 0 < m → m ≤ n → f n ≤ f m
⊢ ∑ k in Ico 1 (2 ^ Nat.zero), f k ≤ ∑ k in range Nat.zero, 2 ^ k • f (2 ^ k)

Next tactic:
simp
theorem le_sum_condensed' (hf : ∀ ⦃m n⦄, 0 < m → m ≤ n → f n ≤ f m) (n : ℕ) :
    (∑ k in Ico 1 (2 ^ n), f k) ≤ ∑ k in range n, 2 ^ k • f (2 ^ k) := by
  induction' n with n ihn
  · simp
  

Proof state:
case succ
M : Type u_1
inst✝ : OrderedAddCommMonoid M
f : ℕ → M
hf : ∀ ⦃m n : ℕ⦄, 0 < m → m ≤ n → f n ≤ f m
n : ℕ
ihn : ∑ k in Ico 1 (2 ^ n), f k ≤ ∑ k in range n, 2 ^ k • f (2 ^ k)
⊢ ∑ k in Ico 1 (2 ^ Nat.succ n), f k ≤ ∑ k in range (Nat.succ n), 2 ^ k • f (2 ^ k)

Next tactic:
suffices (∑ k in Ico (2 ^ n) (2 ^ (n + 1)), f k) ≤ 2 ^ n • f (2 ^ n) by
    rw [sum_range_succ, ← sum_Ico_consecutive]
    exact add_le_add ihn this
    exacts [n.one_le_two_pow, Nat.pow_le_pow_of_le_right zero_lt_two n.le_succ]
theorem le_sum_condensed' (hf : ∀ ⦃m n⦄, 0 < m → m ≤ n → f n ≤ f m) (n : ℕ) :
    (∑ k in Ico 1 (2 ^ n), f k) ≤ ∑ k in range n, 2 ^ k • f (2 ^ k) := by
  induction' n with n ihn
  · simp
  suffices (∑ k in Ico (2 ^ n) (2 ^ (n + 1)), f k) ≤ 2 ^ n • f (2 ^ n) by
    

Proof state:
M : Type u_1
inst✝ : OrderedAddCommMonoid M
f : ℕ → M
hf : ∀ ⦃m n : ℕ⦄, 0 < m → m ≤ n → f n ≤ f m
n : ℕ
ihn : ∑ k in Ico 1 (2 ^ n), f k ≤ ∑ k in range n, 2 ^ k • f (2 ^ k)
this : ∑ k in Ico (2 ^ n) (2 ^ (n + 1)), f k ≤ 2 ^ n • f (2 ^ n)
⊢ ∑ k in Ico 1 (2 ^ Nat.succ n), f k ≤ ∑ k in range (Nat.succ n), 2 ^ k • f (2 ^ k)

Next tactic:
rw [sum_range_succ, ← sum_Ico_consecutive]
theorem le_sum_condensed' (hf : ∀ ⦃m n⦄, 0 < m → m ≤ n → f n ≤ f m) (n : ℕ) :
    (∑ k in Ico 1 (2 ^ n), f k) ≤ ∑ k in range n, 2 ^ k • f (2 ^ k) := by
  induction' n with n ihn
  · simp
  suffices (∑ k in Ico (2 ^ n) (2 ^ (n + 1)), f k) ≤ 2 ^ n • f (2 ^ n) by
    rw [sum_range_succ, ← sum_Ico_consecutive]
    

Proof state:
M : Type u_1
inst✝ : OrderedAddCommMonoid M
f : ℕ → M
hf : ∀ ⦃m n : ℕ⦄, 0 < m → m ≤ n → f n ≤ f m
n : ℕ
ihn : ∑ k in Ico 1 (2 ^ n), f k ≤ ∑ k in range n, 2 ^ k • f (2 ^ k)
this : ∑ k in Ico (2 ^ n) (2 ^ (n + 1)), f k ≤ 2 ^ n • f (2 ^ n)
⊢ ∑ i in Ico 1 ?n, f i + ∑ i in Ico ?n (2 ^ Nat.succ n), f i ≤ ∑ x in range n, 2 ^ x • f (2 ^ x) + 2 ^ n • f (2 ^ n)
case n
M : Type u_1
inst✝ : OrderedAddCommMonoid M
f : ℕ → M
hf : ∀ ⦃m n : ℕ⦄, 0 < m → m ≤ n → f n ≤ f m
n : ℕ
ihn : ∑ k in Ico 1 (2 ^ n), f k ≤ ∑ k in range n, 2 ^ k • f (2 ^ k)
this : ∑ k in Ico (2 ^ n) (2 ^ (n + 1)), f k ≤ 2 ^ n • f (2 ^ n)
⊢ ℕ
case hmn
M : Type u_1
inst✝ : OrderedAddCommMonoid M
f : ℕ → M
hf : ∀ ⦃m n : ℕ⦄, 0 < m → m ≤ n → f n ≤ f m
n : ℕ
ihn : ∑ k in Ico 1 (2 ^ n), f k ≤ ∑ k in range n, 2 ^ k • f (2 ^ k)
this : ∑ k in Ico (2 ^ n) (2 ^ (n + 1)), f k ≤ 2 ^ n • f (2 ^ n)
⊢ 1 ≤ ?n
case hnk
M : Type u_1
inst✝ : OrderedAddCommMonoid M
f : ℕ → M
hf : ∀ ⦃m n : ℕ⦄, 0 < m → m ≤ n → f n ≤ f m
n : ℕ
ihn : ∑ k in Ico 1 (2 ^ n), f k ≤ ∑ k in range n, 2 ^ k • f (2 ^ k)
this : ∑ k in Ico (2 ^ n) (2 ^ (n + 1)), f k ≤ 2 ^ n • f (2 ^ n)
⊢ ?n ≤ 2 ^ Nat.succ n

Next tactic:
exact add_le_add ihn this