l3lab/ntp-mathlib huggingface dataset:
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · 

Proof state:
case inr.intro
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
⊢ ∃ n, ∀ (z : ℍ), g • z = T ^ n • z

Next tactic:
use -((↑ₘg) 0 1)
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · use -((↑ₘg) 0 1)
    

Proof state:
case h
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
⊢ ∀ (z : ℍ), g • z = T ^ (-↑g 0 1) • z

Next tactic:
suffices g = -T ^ (-((↑ₘg) 0 1)) by intro z; conv_lhs => rw [this, SL_neg_smul]
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · use -((↑ₘg) 0 1)
    suffices g = -T ^ (-((↑ₘg) 0 1)) by 

Proof state:
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
this : g = -T ^ (-↑g 0 1)
⊢ ∀ (z : ℍ), g • z = T ^ (-↑g 0 1) • z

Next tactic:
intro z
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · use -((↑ₘg) 0 1)
    suffices g = -T ^ (-((↑ₘg) 0 1)) by intro z; 

Proof state:
g : SL(2, ℤ)
z✝ : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
this : g = -T ^ (-↑g 0 1)
z : ℍ
⊢ g • z = T ^ (-↑g 0 1) • z

Next tactic:
conv_lhs => rw [this, SL_neg_smul]
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · use -((↑ₘg) 0 1)
    suffices g = -T ^ (-((↑ₘg) 0 1)) by intro z; conv_lhs => 

Proof state:
g : SL(2, ℤ)
z✝ : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
this : g = -T ^ (-↑g 0 1)
z : ℍ
| g • z

Next tactic:
rw [this, SL_neg_smul]
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · use -((↑ₘg) 0 1)
    suffices g = -T ^ (-((↑ₘg) 0 1)) by intro z; conv_lhs => rw [this, SL_neg_smul]
    

Proof state:
case h
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
⊢ g = -T ^ (-↑g 0 1)

Next tactic:
ext i j
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · use -((↑ₘg) 0 1)
    suffices g = -T ^ (-((↑ₘg) 0 1)) by intro z; conv_lhs => rw [this, SL_neg_smul]
    ext i j; 

Proof state:
case h.a
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
i j : Fin 2
⊢ ↑g i j = ↑(-T ^ (-↑g 0 1)) i j

Next tactic:
fin_cases i
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · use -((↑ₘg) 0 1)
    suffices g = -T ^ (-((↑ₘg) 0 1)) by intro z; conv_lhs => rw [this, SL_neg_smul]
    ext i j; fin_cases i <;> 

Proof state:
case h.a.head
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
j : Fin 2
⊢ ↑g { val := 0, isLt := (_ : 0 < 2) } j = ↑(-T ^ (-↑g 0 1)) { val := 0, isLt := (_ : 0 < 2) } j

Next tactic:
fin_cases j
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · use -((↑ₘg) 0 1)
    suffices g = -T ^ (-((↑ₘg) 0 1)) by intro z; conv_lhs => rw [this, SL_neg_smul]
    ext i j; fin_cases i <;> 

Proof state:
case h.a.tail.head
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
j : Fin 2
⊢ ↑g { val := 1, isLt := (_ : (fun a => a < 2) 1) } j =
    ↑(-T ^ (-↑g 0 1)) { val := 1, isLt := (_ : (fun a => a < 2) 1) } j

Next tactic:
fin_cases j
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · use -((↑ₘg) 0 1)
    suffices g = -T ^ (-((↑ₘg) 0 1)) by intro z; conv_lhs => rw [this, SL_neg_smul]
    ext i j; fin_cases i <;> fin_cases j <;>
      

Proof state:
case h.a.head.head
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
⊢ ↑g { val := 0, isLt := (_ : 0 < 2) } { val := 0, isLt := (_ : 0 < 2) } =
    ↑(-T ^ (-↑g 0 1)) { val := 0, isLt := (_ : 0 < 2) } { val := 0, isLt := (_ : 0 < 2) }

Next tactic:
simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · use -((↑ₘg) 0 1)
    suffices g = -T ^ (-((↑ₘg) 0 1)) by intro z; conv_lhs => rw [this, SL_neg_smul]
    ext i j; fin_cases i <;> fin_cases j <;>
      

Proof state:
case h.a.head.tail.head
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
⊢ ↑g { val := 0, isLt := (_ : 0 < 2) } { val := 1, isLt := (_ : (fun a => a < 2) 1) } =
    ↑(-T ^ (-↑g 0 1)) { val := 0, isLt := (_ : 0 < 2) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }

Next tactic:
simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · use -((↑ₘg) 0 1)
    suffices g = -T ^ (-((↑ₘg) 0 1)) by intro z; conv_lhs => rw [this, SL_neg_smul]
    ext i j; fin_cases i <;> fin_cases j <;>
      

Proof state:
case h.a.tail.head.head
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
⊢ ↑g { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 0, isLt := (_ : 0 < 2) } =
    ↑(-T ^ (-↑g 0 1)) { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 0, isLt := (_ : 0 < 2) }

Next tactic:
simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
theorem exists_eq_T_zpow_of_c_eq_zero (hc : (↑ₘg) 1 0 = 0) :
    ∃ n : ℤ, ∀ z : ℍ, g • z = T ^ n • z := by
  have had := g.det_coe
  replace had : (↑ₘg) 0 0 * (↑ₘg) 1 1 = 1; · rw [det_fin_two, hc] at had; linarith
  rcases Int.eq_one_or_neg_one_of_mul_eq_one' had with (⟨ha, hd⟩ | ⟨ha, hd⟩)
  · use (↑ₘg) 0 1
    suffices g = T ^ (↑ₘg) 0 1 by intro z; conv_lhs => rw [this]
    ext i j; fin_cases i <;> fin_cases j <;>
      simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
  · use -((↑ₘg) 0 1)
    suffices g = -T ^ (-((↑ₘg) 0 1)) by intro z; conv_lhs => rw [this, SL_neg_smul]
    ext i j; fin_cases i <;> fin_cases j <;>
      

Proof state:
case h.a.tail.head.tail.head
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 0
had : ↑g 0 0 * ↑g 1 1 = 1
ha : ↑g 0 0 = -1
hd : ↑g 1 1 = -1
⊢ ↑g { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 1, isLt := (_ : (fun a => a < 2) 1) } =
    ↑(-T ^ (-↑g 0 1)) { val := 1, isLt := (_ : (fun a => a < 2) 1) } { val := 1, isLt := (_ : (fun a => a < 2) 1) }

Next tactic:
simp [ha, hc, hd, coe_T_zpow, show (1 : Fin (0 + 2)) = (1 : Fin 2) from rfl]
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  

Proof state:
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
⊢ g = T ^ ↑g 0 0 * S * T ^ ↑g 1 1

Next tactic:
have hg := g.det_coe.symm
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  

Proof state:
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : 1 = det ↑g
⊢ g = T ^ ↑g 0 0 * S * T ^ ↑g 1 1

Next tactic:
replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1; · 

Proof state:
case hg
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : 1 = det ↑g
⊢ ↑g 0 1 = ↑g 0 0 * ↑g 1 1 - 1

Next tactic:
rw [det_fin_two, hc] at hg
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1; · rw [det_fin_two, hc] at hg; 

Proof state:
case hg
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : 1 = ↑g 0 0 * ↑g 1 1 - ↑g 0 1 * 1
⊢ ↑g 0 1 = ↑g 0 0 * ↑g 1 1 - 1

Next tactic:
linarith
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1; · rw [det_fin_two, hc] at hg; linarith
  

Proof state:
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : ↑g 0 1 = ↑g 0 0 * ↑g 1 1 - 1
⊢ g = T ^ ↑g 0 0 * S * T ^ ↑g 1 1

Next tactic:
refine' Subtype.ext _
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1; · rw [det_fin_two, hc] at hg; linarith
  refine' Subtype.ext _
  

Proof state:
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : ↑g 0 1 = ↑g 0 0 * ↑g 1 1 - 1
⊢ ↑g = ↑(T ^ ↑g 0 0 * S * T ^ ↑g 1 1)

Next tactic:
conv_lhs => rw [Matrix.eta_fin_two (↑ₘg)]
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1; · rw [det_fin_two, hc] at hg; linarith
  refine' Subtype.ext _
  conv_lhs => 

Proof state:
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : ↑g 0 1 = ↑g 0 0 * ↑g 1 1 - 1
| ↑g

Next tactic:
rw [Matrix.eta_fin_two (↑ₘg)]
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1; · rw [det_fin_two, hc] at hg; linarith
  refine' Subtype.ext _
  conv_lhs => rw [Matrix.eta_fin_two (↑ₘg)]
  

Proof state:
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : ↑g 0 1 = ↑g 0 0 * ↑g 1 1 - 1
⊢ of ![![↑g 0 0, ↑g 0 1], ![↑g 1 0, ↑g 1 1]] = ↑(T ^ ↑g 0 0 * S * T ^ ↑g 1 1)

Next tactic:
rw [hc, hg]
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1; · rw [det_fin_two, hc] at hg; linarith
  refine' Subtype.ext _
  conv_lhs => rw [Matrix.eta_fin_two (↑ₘg)]
  rw [hc, hg]
  

Proof state:
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : ↑g 0 1 = ↑g 0 0 * ↑g 1 1 - 1
⊢ of ![![↑g 0 0, ↑g 0 0 * ↑g 1 1 - 1], ![1, ↑g 1 1]] = ↑(T ^ ↑g 0 0 * S * T ^ ↑g 1 1)

Next tactic:
simp only [coe_mul, coe_T_zpow, coe_S, mul_fin_two]
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1; · rw [det_fin_two, hc] at hg; linarith
  refine' Subtype.ext _
  conv_lhs => rw [Matrix.eta_fin_two (↑ₘg)]
  rw [hc, hg]
  simp only [coe_mul, coe_T_zpow, coe_S, mul_fin_two]
  

Proof state:
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : ↑g 0 1 = ↑g 0 0 * ↑g 1 1 - 1
⊢ of ![![↑g 0 0, ↑g 0 0 * ↑g 1 1 - 1], ![1, ↑g 1 1]] =
    of
      ![![(1 * 0 + ↑g 0 0 * 1) * 1 + (1 * -1 + ↑g 0 0 * 0) * 0,
          (1 * 0 + ↑g 0 0 * 1) * ↑g 1 1 + (1 * -1 + ↑g 0 0 * 0) * 1],
        ![(0 * 0 + 1 * 1) * 1 + (0 * -1 + 1 * 0) * 0, (0 * 0 + 1 * 1) * ↑g 1 1 + (0 * -1 + 1 * 0) * 1]]

Next tactic:
congrm !![?_, ?_; ?_, ?_]
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1; · rw [det_fin_two, hc] at hg; linarith
  refine' Subtype.ext _
  conv_lhs => rw [Matrix.eta_fin_two (↑ₘg)]
  rw [hc, hg]
  simp only [coe_mul, coe_T_zpow, coe_S, mul_fin_two]
  congrm !![?_, ?_; ?_, ?_] <;> 

Proof state:
case refine_1
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : ↑g 0 1 = ↑g 0 0 * ↑g 1 1 - 1
⊢ ↑g 0 0 = (1 * 0 + ↑g 0 0 * 1) * 1 + (1 * -1 + ↑g 0 0 * 0) * 0

Next tactic:
ring
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1; · rw [det_fin_two, hc] at hg; linarith
  refine' Subtype.ext _
  conv_lhs => rw [Matrix.eta_fin_two (↑ₘg)]
  rw [hc, hg]
  simp only [coe_mul, coe_T_zpow, coe_S, mul_fin_two]
  congrm !![?_, ?_; ?_, ?_] <;> 

Proof state:
case refine_2
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : ↑g 0 1 = ↑g 0 0 * ↑g 1 1 - 1
⊢ ↑g 0 0 * ↑g 1 1 - 1 = (1 * 0 + ↑g 0 0 * 1) * ↑g 1 1 + (1 * -1 + ↑g 0 0 * 0) * 1

Next tactic:
ring
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1; · rw [det_fin_two, hc] at hg; linarith
  refine' Subtype.ext _
  conv_lhs => rw [Matrix.eta_fin_two (↑ₘg)]
  rw [hc, hg]
  simp only [coe_mul, coe_T_zpow, coe_S, mul_fin_two]
  congrm !![?_, ?_; ?_, ?_] <;> 

Proof state:
case refine_3
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : ↑g 0 1 = ↑g 0 0 * ↑g 1 1 - 1
⊢ 1 = (0 * 0 + 1 * 1) * 1 + (0 * -1 + 1 * 0) * 0

Next tactic:
ring
theorem g_eq_of_c_eq_one (hc : (↑ₘg) 1 0 = 1) : g = T ^ (↑ₘg) 0 0 * S * T ^ (↑ₘg) 1 1 := by
  have hg := g.det_coe.symm
  replace hg : (↑ₘg) 0 1 = (↑ₘg) 0 0 * (↑ₘg) 1 1 - 1; · rw [det_fin_two, hc] at hg; linarith
  refine' Subtype.ext _
  conv_lhs => rw [Matrix.eta_fin_two (↑ₘg)]
  rw [hc, hg]
  simp only [coe_mul, coe_T_zpow, coe_S, mul_fin_two]
  congrm !![?_, ?_; ?_, ?_] <;> 

Proof state:
case refine_4
g : SL(2, ℤ)
z : ℍ
hc : ↑g 1 0 = 1
hg : ↑g 0 1 = ↑g 0 0 * ↑g 1 1 - 1
⊢ ↑g 1 1 = (0 * 0 + 1 * 1) * ↑g 1 1 + (0 * -1 + 1 * 0) * 1

Next tactic:
ring
/-- If `1 < |z|`, then `|S • z| < 1`. -/
theorem normSq_S_smul_lt_one (h : 1 < normSq z) : normSq ↑(S • z) < 1 := by
  

Proof state:
g : SL(2, ℤ)
z : ℍ
h : 1 < normSq ↑z
⊢ normSq ↑(S • z) < 1

Next tactic:
simpa [coe_S, num, denom] using (inv_lt_inv z.normSq_pos zero_lt_one).mpr h
/-- If `|z| < 1`, then applying `S` strictly decreases `im`. -/
theorem im_lt_im_S_smul (h : normSq z < 1) : z.im < (S • z).im := by
  

Proof state:
g : SL(2, ℤ)
z : ℍ
h : normSq ↑z < 1
⊢ UpperHalfPlane.im z < UpperHalfPlane.im (S • z)

Next tactic:
have : z.im < z.im / normSq (z : ℂ) := by
    have imz : 0 < z.im := im_pos z
    apply (lt_div_iff z.normSq_pos).mpr
    nlinarith
/-- If `|z| < 1`, then applying `S` strictly decreases `im`. -/
theorem im_lt_im_S_smul (h : normSq z < 1) : z.im < (S • z).im := by
  have : z.im < z.im / normSq (z : ℂ) := by
    

Proof state:
g : SL(2, ℤ)
z : ℍ
h : normSq ↑z < 1
⊢ UpperHalfPlane.im z < UpperHalfPlane.im z / normSq ↑z

Next tactic:
have imz : 0 < z.im := im_pos z
/-- If `|z| < 1`, then applying `S` strictly decreases `im`. -/
theorem im_lt_im_S_smul (h : normSq z < 1) : z.im < (S • z).im := by
  have : z.im < z.im / normSq (z : ℂ) := by
    have imz : 0 < z.im := im_pos z
    

Proof state:
g : SL(2, ℤ)
z : ℍ
h : normSq ↑z < 1
imz : 0 < UpperHalfPlane.im z
⊢ UpperHalfPlane.im z < UpperHalfPlane.im z / normSq ↑z

Next tactic:
apply (lt_div_iff z.normSq_pos).mpr
/-- If `|z| < 1`, then applying `S` strictly decreases `im`. -/
theorem im_lt_im_S_smul (h : normSq z < 1) : z.im < (S • z).im := by
  have : z.im < z.im / normSq (z : ℂ) := by
    have imz : 0 < z.im := im_pos z
    apply (lt_div_iff z.normSq_pos).mpr
    

Proof state:
g : SL(2, ℤ)
z : ℍ
h : normSq ↑z < 1
imz : 0 < UpperHalfPlane.im z
⊢ UpperHalfPlane.im z * normSq ↑z < UpperHalfPlane.im z

Next tactic:
nlinarith
/-- If `|z| < 1`, then applying `S` strictly decreases `im`. -/
theorem im_lt_im_S_smul (h : normSq z < 1) : z.im < (S • z).im := by
  have : z.im < z.im / normSq (z : ℂ) := by
    have imz : 0 < z.im := im_pos z
    apply (lt_div_iff z.normSq_pos).mpr
    nlinarith
  

Proof state:
g : SL(2, ℤ)
z : ℍ
h : normSq ↑z < 1
this : UpperHalfPlane.im z < UpperHalfPlane.im z / normSq ↑z
⊢ UpperHalfPlane.im z < UpperHalfPlane.im (S • z)

Next tactic:
convert this
/-- If `|z| < 1`, then applying `S` strictly decreases `im`. -/
theorem im_lt_im_S_smul (h : normSq z < 1) : z.im < (S • z).im := by
  have : z.im < z.im / normSq (z : ℂ) := by
    have imz : 0 < z.im := im_pos z
    apply (lt_div_iff z.normSq_pos).mpr
    nlinarith
  convert this
  

Proof state:
case h.e'_4
g : SL(2, ℤ)
z : ℍ
h : normSq ↑z < 1
this : UpperHalfPlane.im z < UpperHalfPlane.im z / normSq ↑z
⊢ UpperHalfPlane.im (S • z) = UpperHalfPlane.im z / normSq ↑z

Next tactic:
simp only [SpecialLinearGroup.im_smul_eq_div_normSq]
/-- If `|z| < 1`, then applying `S` strictly decreases `im`. -/
theorem im_lt_im_S_smul (h : normSq z < 1) : z.im < (S • z).im := by
  have : z.im < z.im / normSq (z : ℂ) := by
    have imz : 0 < z.im := im_pos z
    apply (lt_div_iff z.normSq_pos).mpr
    nlinarith
  convert this
  simp only [SpecialLinearGroup.im_smul_eq_div_normSq]
  

Proof state:
case h.e'_4
g : SL(2, ℤ)
z : ℍ
h : normSq ↑z < 1
this : UpperHalfPlane.im z < UpperHalfPlane.im z / normSq ↑z
⊢ UpperHalfPlane.im z / normSq (denom (↑S) z) = UpperHalfPlane.im z / normSq ↑z

Next tactic:
simp [denom, coe_S]
theorem abs_two_mul_re_lt_one_of_mem_fdo (h : z ∈ 𝒟ᵒ) : |2 * z.re| < 1 := by
  

Proof state:
g : SL(2, ℤ)
z : ℍ
h : z ∈ 𝒟ᵒ
⊢ |2 * UpperHalfPlane.re z| < 1

Next tactic:
rw [abs_mul, abs_two, ← lt_div_iff' (zero_lt_two' ℝ)]
theorem abs_two_mul_re_lt_one_of_mem_fdo (h : z ∈ 𝒟ᵒ) : |2 * z.re| < 1 := by
  rw [abs_mul, abs_two, ← lt_div_iff' (zero_lt_two' ℝ)]
  

Proof state:
g : SL(2, ℤ)
z : ℍ
h : z ∈ 𝒟ᵒ
⊢ |UpperHalfPlane.re z| < 1 / 2

Next tactic:
exact h.2
theorem three_lt_four_mul_im_sq_of_mem_fdo (h : z ∈ 𝒟ᵒ) : 3 < 4 * z.im ^ 2 := by
  

Proof state:
g : SL(2, ℤ)
z : ℍ
h : z ∈ 𝒟ᵒ
⊢ 3 < 4 * UpperHalfPlane.im z ^ 2

Next tactic:
have : 1 < z.re * z.re + z.im * z.im := by simpa [Complex.normSq_apply] using h.1
theorem three_lt_four_mul_im_sq_of_mem_fdo (h : z ∈ 𝒟ᵒ) : 3 < 4 * z.im ^ 2 := by
  have : 1 < z.re * z.re + z.im * z.im := by 

Proof state:
g : SL(2, ℤ)
z : ℍ
h : z ∈ 𝒟ᵒ
⊢ 1 < UpperHalfPlane.re z * UpperHalfPlane.re z + UpperHalfPlane.im z * UpperHalfPlane.im z

Next tactic:
simpa [Complex.normSq_apply] using h.1
theorem three_lt_four_mul_im_sq_of_mem_fdo (h : z ∈ 𝒟ᵒ) : 3 < 4 * z.im ^ 2 := by
  have : 1 < z.re * z.re + z.im * z.im := by simpa [Complex.normSq_apply] using h.1
  

Proof state:
g : SL(2, ℤ)
z : ℍ
h : z ∈ 𝒟ᵒ
this : 1 < UpperHalfPlane.re z * UpperHalfPlane.re z + UpperHalfPlane.im z * UpperHalfPlane.im z
⊢ 3 < 4 * UpperHalfPlane.im z ^ 2

Next tactic:
have := h.2
theorem three_lt_four_mul_im_sq_of_mem_fdo (h : z ∈ 𝒟ᵒ) : 3 < 4 * z.im ^ 2 := by
  have : 1 < z.re * z.re + z.im * z.im := by simpa [Complex.normSq_apply] using h.1
  have := h.2
  

Proof state:
g : SL(2, ℤ)
z : ℍ
h : z ∈ 𝒟ᵒ
this✝ : 1 < UpperHalfPlane.re z * UpperHalfPlane.re z + UpperHalfPlane.im z * UpperHalfPlane.im z
this : |UpperHalfPlane.re z| < 1 / 2
⊢ 3 < 4 * UpperHalfPlane.im z ^ 2

Next tactic:
cases abs_cases z.re
theorem three_lt_four_mul_im_sq_of_mem_fdo (h : z ∈ 𝒟ᵒ) : 3 < 4 * z.im ^ 2 := by
  have : 1 < z.re * z.re + z.im * z.im := by simpa [Complex.normSq_apply] using h.1
  have := h.2
  cases abs_cases z.re <;> 

Proof state:
case inl
g : SL(2, ℤ)
z : ℍ
h : z ∈ 𝒟ᵒ
this✝ : 1 < UpperHalfPlane.re z * UpperHalfPlane.re z + UpperHalfPlane.im z * UpperHalfPlane.im z
this : |UpperHalfPlane.re z| < 1 / 2
h✝ : |UpperHalfPlane.re z| = UpperHalfPlane.re z ∧ 0 ≤ UpperHalfPlane.re z
⊢ 3 < 4 * UpperHalfPlane.im z ^ 2

Next tactic:
nlinarith
theorem three_lt_four_mul_im_sq_of_mem_fdo (h : z ∈ 𝒟ᵒ) : 3 < 4 * z.im ^ 2 := by
  have : 1 < z.re * z.re + z.im * z.im := by simpa [Complex.normSq_apply] using h.1
  have := h.2
  cases abs_cases z.re <;> 

Proof state:
case inr
g : SL(2, ℤ)
z : ℍ
h : z ∈ 𝒟ᵒ
this✝ : 1 < UpperHalfPlane.re z * UpperHalfPlane.re z + UpperHalfPlane.im z * UpperHalfPlane.im z
this : |UpperHalfPlane.re z| < 1 / 2
h✝ : |UpperHalfPlane.re z| = -UpperHalfPlane.re z ∧ UpperHalfPlane.re z < 0
⊢ 3 < 4 * UpperHalfPlane.im z ^ 2

Next tactic:
nlinarith
/-- If `z ∈ 𝒟ᵒ`, and `n : ℤ`, then `|z + n| > 1`. -/
theorem one_lt_normSq_T_zpow_smul (hz : z ∈ 𝒟ᵒ) (n : ℤ) : 1 < normSq (T ^ n • z : ℍ) := by
  

Proof state:
g : SL(2, ℤ)
z : ℍ
hz : z ∈ 𝒟ᵒ
n : ℤ
⊢ 1 < normSq ↑(T ^ n • z)

Next tactic:
have hz₁ : 1 < z.re * z.re + z.im * z.im := hz.1