l3lab/ntp-mathlib huggingface dataset:
instance subgroup_on_glpos : IsScalarTower Γ GL(2, ℝ)⁺ ℍ where
  smul_assoc := by
    intro s g z
    

Proof state:
Γ : Subgroup SL(2, ℤ)
s : ↥Γ
g : ↥GL(2, ℝ)⁺
z : ℍ
⊢ (s • g) • z = s • g • z

Next tactic:
simp only [subgroup_on_glpos_smul_apply]
instance subgroup_on_glpos : IsScalarTower Γ GL(2, ℝ)⁺ ℍ where
  smul_assoc := by
    intro s g z
    simp only [subgroup_on_glpos_smul_apply]
    

Proof state:
Γ : Subgroup SL(2, ℤ)
s : ↥Γ
g : ↥GL(2, ℝ)⁺
z : ℍ
⊢ (↑↑s * g) • z = s • g • z

Next tactic:
apply mul_smul'
instance subgroup_to_SL_tower : IsScalarTower Γ SL(2, ℤ) ℍ where
  smul_assoc s g z := by
    

Proof state:
Γ : Subgroup SL(2, ℤ)
s : ↥Γ
g : SL(2, ℤ)
z : ℍ
⊢ (s • g) • z = s • g • z

Next tactic:
rw [subgroup_on_SL_apply]
instance subgroup_to_SL_tower : IsScalarTower Γ SL(2, ℤ) ℍ where
  smul_assoc s g z := by
    rw [subgroup_on_SL_apply]
    

Proof state:
Γ : Subgroup SL(2, ℤ)
s : ↥Γ
g : SL(2, ℤ)
z : ℍ
⊢ (↑s * g) • z = s • g • z

Next tactic:
apply MulAction.mul_smul
@[simp]
theorem neg_smul (g : GL(2, ℝ)⁺) (z : ℍ) : -g • z = g • z := by
  

Proof state:
g : ↥GL(2, ℝ)⁺
z : ℍ
⊢ -g • z = g • z

Next tactic:
ext1
@[simp]
theorem neg_smul (g : GL(2, ℝ)⁺) (z : ℍ) : -g • z = g • z := by
  ext1
  

Proof state:
case h
g : ↥GL(2, ℝ)⁺
z : ℍ
⊢ ↑(-g • z) = ↑(g • z)

Next tactic:
change _ / _ = _ / _
@[simp]
theorem neg_smul (g : GL(2, ℝ)⁺) (z : ℍ) : -g • z = g • z := by
  ext1
  change _ / _ = _ / _
  

Proof state:
case h
g : ↥GL(2, ℝ)⁺
z : ℍ
⊢ num (-g) z / denom (-g) z = num g z / denom g z

Next tactic:
field_simp [denom_ne_zero]
@[simp]
theorem neg_smul (g : GL(2, ℝ)⁺) (z : ℍ) : -g • z = g • z := by
  ext1
  change _ / _ = _ / _
  field_simp [denom_ne_zero]
  

Proof state:
case h
g : ↥GL(2, ℝ)⁺
z : ℍ
⊢ num (-g) z * denom g z = num g z * denom (-g) z

Next tactic:
simp only [num, denom, Complex.ofReal_neg, neg_mul, GLPos.coe_neg_GL, Units.val_neg, neg_apply]
@[simp]
theorem neg_smul (g : GL(2, ℝ)⁺) (z : ℍ) : -g • z = g • z := by
  ext1
  change _ / _ = _ / _
  field_simp [denom_ne_zero]
  simp only [num, denom, Complex.ofReal_neg, neg_mul, GLPos.coe_neg_GL, Units.val_neg, neg_apply]
  

Proof state:
case h
g : ↥GL(2, ℝ)⁺
z : ℍ
⊢ (-(↑(↑↑g 0 0) * ↑z) + -↑(↑↑g 0 1)) * (↑(↑↑g 1 0) * ↑z + ↑(↑↑g 1 1)) =
    (↑(↑↑g 0 0) * ↑z + ↑(↑↑g 0 1)) * (-(↑(↑↑g 1 0) * ↑z) + -↑(↑↑g 1 1))

Next tactic:
ring_nf
@[simp high]
theorem SL_neg_smul (g : SL(2, ℤ)) (z : ℍ) : -g • z = g • z := by
  

Proof state:
g✝ : SL(2, ℤ)
z✝ : ℍ
Γ : Subgroup SL(2, ℤ)
g : SL(2, ℤ)
z : ℍ
⊢ -g • z = g • z

Next tactic:
simp only [coe_GLPos_neg, sl_moeb, coe_int_neg, neg_smul, coe']
theorem c_mul_im_sq_le_normSq_denom (z : ℍ) (g : SL(2, ℝ)) :
    ((↑ₘg 1 0 : ℝ) * z.im) ^ 2 ≤ Complex.normSq (denom g z) := by
  

Proof state:
g✝ : SL(2, ℤ)
z✝ : ℍ
Γ : Subgroup SL(2, ℤ)
z : ℍ
g : SL(2, ℝ)
⊢ (↑↑(toGLPos g) 1 0 * im z) ^ 2 ≤ Complex.normSq (denom (toGLPos g) z)

Next tactic:
let c := (↑ₘg 1 0 : ℝ)
theorem c_mul_im_sq_le_normSq_denom (z : ℍ) (g : SL(2, ℝ)) :
    ((↑ₘg 1 0 : ℝ) * z.im) ^ 2 ≤ Complex.normSq (denom g z) := by
  let c := (↑ₘg 1 0 : ℝ)
  

Proof state:
g✝ : SL(2, ℤ)
z✝ : ℍ
Γ : Subgroup SL(2, ℤ)
z : ℍ
g : SL(2, ℝ)
c : ℝ := ↑↑(toGLPos g) 1 0
⊢ (↑↑(toGLPos g) 1 0 * im z) ^ 2 ≤ Complex.normSq (denom (toGLPos g) z)

Next tactic:
let d := (↑ₘg 1 1 : ℝ)
theorem c_mul_im_sq_le_normSq_denom (z : ℍ) (g : SL(2, ℝ)) :
    ((↑ₘg 1 0 : ℝ) * z.im) ^ 2 ≤ Complex.normSq (denom g z) := by
  let c := (↑ₘg 1 0 : ℝ)
  let d := (↑ₘg 1 1 : ℝ)
  

Proof state:
g✝ : SL(2, ℤ)
z✝ : ℍ
Γ : Subgroup SL(2, ℤ)
z : ℍ
g : SL(2, ℝ)
c : ℝ := ↑↑(toGLPos g) 1 0
d : ℝ := ↑↑(toGLPos g) 1 1
⊢ (↑↑(toGLPos g) 1 0 * im z) ^ 2 ≤ Complex.normSq (denom (toGLPos g) z)

Next tactic:
calc
    (c * z.im) ^ 2 ≤ (c * z.im) ^ 2 + (c * z.re + d) ^ 2 := by nlinarith
    _ = Complex.normSq (denom g z) := by dsimp [denom, Complex.normSq]; ring
theorem c_mul_im_sq_le_normSq_denom (z : ℍ) (g : SL(2, ℝ)) :
    ((↑ₘg 1 0 : ℝ) * z.im) ^ 2 ≤ Complex.normSq (denom g z) := by
  let c := (↑ₘg 1 0 : ℝ)
  let d := (↑ₘg 1 1 : ℝ)
  calc
    (c * z.im) ^ 2 ≤ (c * z.im) ^ 2 + (c * z.re + d) ^ 2 := by 

Proof state:
g✝ : SL(2, ℤ)
z✝ : ℍ
Γ : Subgroup SL(2, ℤ)
z : ℍ
g : SL(2, ℝ)
c : ℝ := ↑↑(toGLPos g) 1 0
d : ℝ := ↑↑(toGLPos g) 1 1
⊢ (c * im z) ^ 2 ≤ (c * im z) ^ 2 + (c * re z + d) ^ 2

Next tactic:
nlinarith
theorem c_mul_im_sq_le_normSq_denom (z : ℍ) (g : SL(2, ℝ)) :
    ((↑ₘg 1 0 : ℝ) * z.im) ^ 2 ≤ Complex.normSq (denom g z) := by
  let c := (↑ₘg 1 0 : ℝ)
  let d := (↑ₘg 1 1 : ℝ)
  calc
    (c * z.im) ^ 2 ≤ (c * z.im) ^ 2 + (c * z.re + d) ^ 2 := by nlinarith
    _ = Complex.normSq (denom g z) := by 

Proof state:
g✝ : SL(2, ℤ)
z✝ : ℍ
Γ : Subgroup SL(2, ℤ)
z : ℍ
g : SL(2, ℝ)
c : ℝ := ↑↑(toGLPos g) 1 0
d : ℝ := ↑↑(toGLPos g) 1 1
⊢ (c * im z) ^ 2 + (c * re z + d) ^ 2 = Complex.normSq (denom (toGLPos g) z)

Next tactic:
dsimp [denom, Complex.normSq]
theorem c_mul_im_sq_le_normSq_denom (z : ℍ) (g : SL(2, ℝ)) :
    ((↑ₘg 1 0 : ℝ) * z.im) ^ 2 ≤ Complex.normSq (denom g z) := by
  let c := (↑ₘg 1 0 : ℝ)
  let d := (↑ₘg 1 1 : ℝ)
  calc
    (c * z.im) ^ 2 ≤ (c * z.im) ^ 2 + (c * z.re + d) ^ 2 := by nlinarith
    _ = Complex.normSq (denom g z) := by dsimp [denom, Complex.normSq]; 

Proof state:
g✝ : SL(2, ℤ)
z✝ : ℍ
Γ : Subgroup SL(2, ℤ)
z : ℍ
g : SL(2, ℝ)
c : ℝ := ↑↑(toGLPos g) 1 0
d : ℝ := ↑↑(toGLPos g) 1 1
⊢ (↑g 1 0 * im z) ^ 2 + (↑g 1 0 * re z + ↑g 1 1) ^ 2 =
    (↑g 1 0 * re z - 0 * im z + ↑g 1 1) * (↑g 1 0 * re z - 0 * im z + ↑g 1 1) +
      (↑g 1 0 * im z + 0 * re z + 0) * (↑g 1 0 * im z + 0 * re z + 0)

Next tactic:
ring
nonrec theorem SpecialLinearGroup.im_smul_eq_div_normSq :
    (g • z).im = z.im / Complex.normSq (denom g z) := by
  

Proof state:
g : SL(2, ℤ)
z : ℍ
Γ : Subgroup SL(2, ℤ)
⊢ im (g • z) = im z / Complex.normSq (denom (↑g) z)

Next tactic:
convert im_smul_eq_div_normSq g z
nonrec theorem SpecialLinearGroup.im_smul_eq_div_normSq :
    (g • z).im = z.im / Complex.normSq (denom g z) := by
  convert im_smul_eq_div_normSq g z
  

Proof state:
case h.e'_3.h.e'_5
g : SL(2, ℤ)
z : ℍ
Γ : Subgroup SL(2, ℤ)
⊢ im z = det ↑↑↑g * im z

Next tactic:
simp only [GeneralLinearGroup.val_det_apply, coe_GLPos_coe_GL_coe_matrix,
    Int.coe_castRingHom, (g : SL(2, ℝ)).prop, one_mul, coe']
theorem denom_apply (g : SL(2, ℤ)) (z : ℍ) :
    denom g z = (↑g : Matrix (Fin 2) (Fin 2) ℤ) 1 0 * z + (↑g : Matrix (Fin 2) (Fin 2) ℤ) 1 1 := by
  

Proof state:
g✝ : SL(2, ℤ)
z✝ : ℍ
Γ : Subgroup SL(2, ℤ)
g : SL(2, ℤ)
z : ℍ
⊢ denom (↑g) z = ↑(↑g 1 0) * ↑z + ↑(↑g 1 1)

Next tactic:
simp [denom, coe']
instance posRealAction : MulAction { x : ℝ // 0 < x } ℍ where
  smul x z := mk ((x : ℝ) • (z : ℂ)) <| by 

Proof state:
x : { x // 0 < x }
z : ℍ
⊢ 0 < (↑x • ↑z).im

Next tactic:
simpa using mul_pos x.2 z.2
instance : AddAction ℝ ℍ where
  vadd x z := mk (x + z) <| by 

Proof state:
x : ℝ
z : ℍ
⊢ 0 < (↑x + ↑z).im

Next tactic:
simpa using z.im_pos
instance : AddAction ℝ ℍ where
  vadd x z := mk (x + z) <| by simpa using z.im_pos
  zero_vadd _ := Subtype.ext <| by 

Proof state:
x✝ : ℍ
⊢ ↑(0 +ᵥ x✝) = ↑x✝

Next tactic:
simp [HVAdd.hVAdd]
instance : AddAction ℝ ℍ where
  vadd x z := mk (x + z) <| by simpa using z.im_pos
  zero_vadd _ := Subtype.ext <| by simp [HVAdd.hVAdd]
  add_vadd x y z := Subtype.ext <| by 

Proof state:
x y : ℝ
z : ℍ
⊢ ↑(x + y +ᵥ z) = ↑(x +ᵥ (y +ᵥ z))

Next tactic:
simp [HVAdd.hVAdd, add_assoc]
theorem modular_S_smul (z : ℍ) : ModularGroup.S • z = mk (-z : ℂ)⁻¹ z.im_inv_neg_coe_pos := by
  

Proof state:
z : ℍ
⊢ ModularGroup.S • z = mk (-↑z)⁻¹ (_ : 0 < (-↑z)⁻¹.im)

Next tactic:
rw [specialLinearGroup_apply]
theorem modular_S_smul (z : ℍ) : ModularGroup.S • z = mk (-z : ℂ)⁻¹ z.im_inv_neg_coe_pos := by
  rw [specialLinearGroup_apply]; 

Proof state:
z : ℍ
⊢ mk
      ((↑((algebraMap ℤ ℝ) (↑↑ModularGroup.S 0 0)) * ↑z + ↑((algebraMap ℤ ℝ) (↑↑ModularGroup.S 0 1))) /
        (↑((algebraMap ℤ ℝ) (↑↑ModularGroup.S 1 0)) * ↑z + ↑((algebraMap ℤ ℝ) (↑↑ModularGroup.S 1 1))))
      (_ : 0 < (↑(ModularGroup.S • z)).im) =
    mk (-↑z)⁻¹ (_ : 0 < (-↑z)⁻¹.im)

Next tactic:
simp [ModularGroup.S, neg_div, inv_neg, coeToGL]
theorem modular_T_zpow_smul (z : ℍ) (n : ℤ) : ModularGroup.T ^ n • z = (n : ℝ) +ᵥ z := by
  

Proof state:
z : ℍ
n : ℤ
⊢ ModularGroup.T ^ n • z = ↑n +ᵥ z

Next tactic:
rw [← ext_iff, coe_vadd, add_comm, specialLinearGroup_apply, coe_mk]
theorem modular_T_zpow_smul (z : ℍ) (n : ℤ) : ModularGroup.T ^ n • z = (n : ℝ) +ᵥ z := by
  rw [← ext_iff, coe_vadd, add_comm, specialLinearGroup_apply, coe_mk]
  -- Porting note: added `coeToGL` and merged `rw` and `simp`
  

Proof state:
z : ℍ
n : ℤ
⊢ (↑((algebraMap ℤ ℝ) (↑↑(ModularGroup.T ^ n) 0 0)) * ↑z + ↑((algebraMap ℤ ℝ) (↑↑(ModularGroup.T ^ n) 0 1))) /
      (↑((algebraMap ℤ ℝ) (↑↑(ModularGroup.T ^ n) 1 0)) * ↑z + ↑((algebraMap ℤ ℝ) (↑↑(ModularGroup.T ^ n) 1 1))) =
    ↑z + ↑↑n

Next tactic:
simp [coeToGL, ModularGroup.coe_T_zpow,
    of_apply, cons_val_zero, algebraMap.coe_one, Complex.ofReal_one, one_mul, cons_val_one,
    head_cons, algebraMap.coe_zero, zero_mul, zero_add, div_one]
theorem modular_T_smul (z : ℍ) : ModularGroup.T • z = (1 : ℝ) +ᵥ z := by
  

Proof state:
z : ℍ
⊢ ModularGroup.T • z = 1 +ᵥ z

Next tactic:
simpa only [Int.cast_one] using modular_T_zpow_smul z 1
theorem exists_SL2_smul_eq_of_apply_zero_one_eq_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 = 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v : ℝ), (g • · : ℍ → ℍ) = (v +ᵥ ·) ∘ (u • ·) := by
  

Proof state:
g : SL(2, ℝ)
hc : ↑↑g 1 0 = 0
⊢ ∃ u v, (fun x => g • x) = (fun x => v +ᵥ x) ∘ fun x => u • x

Next tactic:
obtain ⟨a, b, ha, rfl⟩ := g.fin_two_exists_eq_mk_of_apply_zero_one_eq_zero hc
theorem exists_SL2_smul_eq_of_apply_zero_one_eq_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 = 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v : ℝ), (g • · : ℍ → ℍ) = (v +ᵥ ·) ∘ (u • ·) := by
  obtain ⟨a, b, ha, rfl⟩ := g.fin_two_exists_eq_mk_of_apply_zero_one_eq_zero hc
  

Proof state:
case intro.intro.intro
a b : ℝ
ha : a ≠ 0
hc : ↑↑{ val := of ![![a, b], ![0, a⁻¹]], property := (_ : det (of ![![a, b], ![0, a⁻¹]]) = 1) } 1 0 = 0
⊢ ∃ u v,
    (fun x => { val := of ![![a, b], ![0, a⁻¹]], property := (_ : det (of ![![a, b], ![0, a⁻¹]]) = 1) } • x) =
      (fun x => v +ᵥ x) ∘ fun x => u • x

Next tactic:
refine' ⟨⟨_, mul_self_pos.mpr ha⟩, b * a, _⟩
theorem exists_SL2_smul_eq_of_apply_zero_one_eq_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 = 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v : ℝ), (g • · : ℍ → ℍ) = (v +ᵥ ·) ∘ (u • ·) := by
  obtain ⟨a, b, ha, rfl⟩ := g.fin_two_exists_eq_mk_of_apply_zero_one_eq_zero hc
  refine' ⟨⟨_, mul_self_pos.mpr ha⟩, b * a, _⟩
  

Proof state:
case intro.intro.intro
a b : ℝ
ha : a ≠ 0
hc : ↑↑{ val := of ![![a, b], ![0, a⁻¹]], property := (_ : det (of ![![a, b], ![0, a⁻¹]]) = 1) } 1 0 = 0
⊢ (fun x => { val := of ![![a, b], ![0, a⁻¹]], property := (_ : det (of ![![a, b], ![0, a⁻¹]]) = 1) } • x) =
    (fun x => b * a +ᵥ x) ∘ fun x => { val := a * a, property := (_ : 0 < a * a) } • x

Next tactic:
ext1 ⟨z, hz⟩
theorem exists_SL2_smul_eq_of_apply_zero_one_eq_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 = 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v : ℝ), (g • · : ℍ → ℍ) = (v +ᵥ ·) ∘ (u • ·) := by
  obtain ⟨a, b, ha, rfl⟩ := g.fin_two_exists_eq_mk_of_apply_zero_one_eq_zero hc
  refine' ⟨⟨_, mul_self_pos.mpr ha⟩, b * a, _⟩
  ext1 ⟨z, hz⟩; 

Proof state:
case intro.intro.intro.h.mk
a b : ℝ
ha : a ≠ 0
hc : ↑↑{ val := of ![![a, b], ![0, a⁻¹]], property := (_ : det (of ![![a, b], ![0, a⁻¹]]) = 1) } 1 0 = 0
z : ℂ
hz : 0 < z.im
⊢ { val := of ![![a, b], ![0, a⁻¹]], property := (_ : det (of ![![a, b], ![0, a⁻¹]]) = 1) } •
      { val := z, property := hz } =
    ((fun x => b * a +ᵥ x) ∘ fun x => { val := a * a, property := (_ : 0 < a * a) } • x) { val := z, property := hz }

Next tactic:
ext1
theorem exists_SL2_smul_eq_of_apply_zero_one_eq_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 = 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v : ℝ), (g • · : ℍ → ℍ) = (v +ᵥ ·) ∘ (u • ·) := by
  obtain ⟨a, b, ha, rfl⟩ := g.fin_two_exists_eq_mk_of_apply_zero_one_eq_zero hc
  refine' ⟨⟨_, mul_self_pos.mpr ha⟩, b * a, _⟩
  ext1 ⟨z, hz⟩; ext1
  

Proof state:
case intro.intro.intro.h.mk.h
a b : ℝ
ha : a ≠ 0
hc : ↑↑{ val := of ![![a, b], ![0, a⁻¹]], property := (_ : det (of ![![a, b], ![0, a⁻¹]]) = 1) } 1 0 = 0
z : ℂ
hz : 0 < z.im
⊢ ↑({ val := of ![![a, b], ![0, a⁻¹]], property := (_ : det (of ![![a, b], ![0, a⁻¹]]) = 1) } •
        { val := z, property := hz }) =
    ↑(((fun x => b * a +ᵥ x) ∘ fun x => { val := a * a, property := (_ : 0 < a * a) } • x) { val := z, property := hz })

Next tactic:
suffices ↑a * z * a + b * a = b * a + a * a * z by
    -- Porting note: added `coeToGL` and merged `rw` and `simpa`
    simpa [coeToGL, specialLinearGroup_apply, add_mul]
theorem exists_SL2_smul_eq_of_apply_zero_one_eq_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 = 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v : ℝ), (g • · : ℍ → ℍ) = (v +ᵥ ·) ∘ (u • ·) := by
  obtain ⟨a, b, ha, rfl⟩ := g.fin_two_exists_eq_mk_of_apply_zero_one_eq_zero hc
  refine' ⟨⟨_, mul_self_pos.mpr ha⟩, b * a, _⟩
  ext1 ⟨z, hz⟩; ext1
  suffices ↑a * z * a + b * a = b * a + a * a * z by
    -- Porting note: added `coeToGL` and merged `rw` and `simpa`
    

Proof state:
a b : ℝ
ha : a ≠ 0
hc : ↑↑{ val := of ![![a, b], ![0, a⁻¹]], property := (_ : det (of ![![a, b], ![0, a⁻¹]]) = 1) } 1 0 = 0
z : ℂ
hz : 0 < z.im
this : ↑a * z * ↑a + ↑b * ↑a = ↑b * ↑a + ↑a * ↑a * z
⊢ ↑({ val := of ![![a, b], ![0, a⁻¹]], property := (_ : det (of ![![a, b], ![0, a⁻¹]]) = 1) } •
        { val := z, property := hz }) =
    ↑(((fun x => b * a +ᵥ x) ∘ fun x => { val := a * a, property := (_ : 0 < a * a) } • x) { val := z, property := hz })

Next tactic:
simpa [coeToGL, specialLinearGroup_apply, add_mul]
theorem exists_SL2_smul_eq_of_apply_zero_one_eq_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 = 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v : ℝ), (g • · : ℍ → ℍ) = (v +ᵥ ·) ∘ (u • ·) := by
  obtain ⟨a, b, ha, rfl⟩ := g.fin_two_exists_eq_mk_of_apply_zero_one_eq_zero hc
  refine' ⟨⟨_, mul_self_pos.mpr ha⟩, b * a, _⟩
  ext1 ⟨z, hz⟩; ext1
  suffices ↑a * z * a + b * a = b * a + a * a * z by
    -- Porting note: added `coeToGL` and merged `rw` and `simpa`
    simpa [coeToGL, specialLinearGroup_apply, add_mul]
  

Proof state:
case intro.intro.intro.h.mk.h
a b : ℝ
ha : a ≠ 0
hc : ↑↑{ val := of ![![a, b], ![0, a⁻¹]], property := (_ : det (of ![![a, b], ![0, a⁻¹]]) = 1) } 1 0 = 0
z : ℂ
hz : 0 < z.im
⊢ ↑a * z * ↑a + ↑b * ↑a = ↑b * ↑a + ↑a * ↑a * z

Next tactic:
ring
theorem exists_SL2_smul_eq_of_apply_zero_one_ne_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 ≠ 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v w : ℝ),
      (g • · : ℍ → ℍ) =
        (w +ᵥ ·) ∘ (ModularGroup.S • · : ℍ → ℍ) ∘ (v +ᵥ · : ℍ → ℍ) ∘ (u • · : ℍ → ℍ) := by
  

Proof state:
g : SL(2, ℝ)
hc : ↑↑g 1 0 ≠ 0
⊢ ∃ u v w, (fun x => g • x) = (fun x => w +ᵥ x) ∘ (fun x => ModularGroup.S • x) ∘ (fun x => v +ᵥ x) ∘ fun x => u • x

Next tactic:
have h_denom := denom_ne_zero g
theorem exists_SL2_smul_eq_of_apply_zero_one_ne_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 ≠ 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v w : ℝ),
      (g • · : ℍ → ℍ) =
        (w +ᵥ ·) ∘ (ModularGroup.S • · : ℍ → ℍ) ∘ (v +ᵥ · : ℍ → ℍ) ∘ (u • · : ℍ → ℍ) := by
  have h_denom := denom_ne_zero g
  

Proof state:
g : SL(2, ℝ)
hc : ↑↑g 1 0 ≠ 0
h_denom : ∀ (z : ℍ), denom (toGLPos g) z ≠ 0
⊢ ∃ u v w, (fun x => g • x) = (fun x => w +ᵥ x) ∘ (fun x => ModularGroup.S • x) ∘ (fun x => v +ᵥ x) ∘ fun x => u • x

Next tactic:
induction' g using Matrix.SpecialLinearGroup.fin_two_induction with a b c d h
theorem exists_SL2_smul_eq_of_apply_zero_one_ne_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 ≠ 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v w : ℝ),
      (g • · : ℍ → ℍ) =
        (w +ᵥ ·) ∘ (ModularGroup.S • · : ℍ → ℍ) ∘ (v +ᵥ · : ℍ → ℍ) ∘ (u • · : ℍ → ℍ) := by
  have h_denom := denom_ne_zero g
  induction' g using Matrix.SpecialLinearGroup.fin_two_induction with a b c d h
  

Proof state:
case h
a b c d : ℝ
h : a * d - b * c = 1
hc : ↑↑{ val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) } 1 0 ≠ 0
h_denom :
  ∀ (z : ℍ), denom (toGLPos { val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) }) z ≠ 0
⊢ ∃ u v w,
    (fun x => { val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) } • x) =
      (fun x => w +ᵥ x) ∘ (fun x => ModularGroup.S • x) ∘ (fun x => v +ᵥ x) ∘ fun x => u • x

Next tactic:
replace hc : c ≠ 0
theorem exists_SL2_smul_eq_of_apply_zero_one_ne_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 ≠ 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v w : ℝ),
      (g • · : ℍ → ℍ) =
        (w +ᵥ ·) ∘ (ModularGroup.S • · : ℍ → ℍ) ∘ (v +ᵥ · : ℍ → ℍ) ∘ (u • · : ℍ → ℍ) := by
  have h_denom := denom_ne_zero g
  induction' g using Matrix.SpecialLinearGroup.fin_two_induction with a b c d h
  replace hc : c ≠ 0; · 

Proof state:
case hc
a b c d : ℝ
h : a * d - b * c = 1
hc : ↑↑{ val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) } 1 0 ≠ 0
h_denom :
  ∀ (z : ℍ), denom (toGLPos { val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) }) z ≠ 0
⊢ c ≠ 0

Next tactic:
simpa using hc
theorem exists_SL2_smul_eq_of_apply_zero_one_ne_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 ≠ 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v w : ℝ),
      (g • · : ℍ → ℍ) =
        (w +ᵥ ·) ∘ (ModularGroup.S • · : ℍ → ℍ) ∘ (v +ᵥ · : ℍ → ℍ) ∘ (u • · : ℍ → ℍ) := by
  have h_denom := denom_ne_zero g
  induction' g using Matrix.SpecialLinearGroup.fin_two_induction with a b c d h
  replace hc : c ≠ 0; · simpa using hc
  

Proof state:
case h
a b c d : ℝ
h : a * d - b * c = 1
h_denom :
  ∀ (z : ℍ), denom (toGLPos { val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) }) z ≠ 0
hc : c ≠ 0
⊢ ∃ u v w,
    (fun x => { val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) } • x) =
      (fun x => w +ᵥ x) ∘ (fun x => ModularGroup.S • x) ∘ (fun x => v +ᵥ x) ∘ fun x => u • x

Next tactic:
refine' ⟨⟨_, mul_self_pos.mpr hc⟩, c * d, a / c, _⟩
theorem exists_SL2_smul_eq_of_apply_zero_one_ne_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 ≠ 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v w : ℝ),
      (g • · : ℍ → ℍ) =
        (w +ᵥ ·) ∘ (ModularGroup.S • · : ℍ → ℍ) ∘ (v +ᵥ · : ℍ → ℍ) ∘ (u • · : ℍ → ℍ) := by
  have h_denom := denom_ne_zero g
  induction' g using Matrix.SpecialLinearGroup.fin_two_induction with a b c d h
  replace hc : c ≠ 0; · simpa using hc
  refine' ⟨⟨_, mul_self_pos.mpr hc⟩, c * d, a / c, _⟩
  

Proof state:
case h
a b c d : ℝ
h : a * d - b * c = 1
h_denom :
  ∀ (z : ℍ), denom (toGLPos { val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) }) z ≠ 0
hc : c ≠ 0
⊢ (fun x => { val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) } • x) =
    (fun x => a / c +ᵥ x) ∘
      (fun x => ModularGroup.S • x) ∘ (fun x => c * d +ᵥ x) ∘ fun x => { val := c * c, property := (_ : 0 < c * c) } • x

Next tactic:
ext1 ⟨z, hz⟩
theorem exists_SL2_smul_eq_of_apply_zero_one_ne_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 ≠ 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v w : ℝ),
      (g • · : ℍ → ℍ) =
        (w +ᵥ ·) ∘ (ModularGroup.S • · : ℍ → ℍ) ∘ (v +ᵥ · : ℍ → ℍ) ∘ (u • · : ℍ → ℍ) := by
  have h_denom := denom_ne_zero g
  induction' g using Matrix.SpecialLinearGroup.fin_two_induction with a b c d h
  replace hc : c ≠ 0; · simpa using hc
  refine' ⟨⟨_, mul_self_pos.mpr hc⟩, c * d, a / c, _⟩
  ext1 ⟨z, hz⟩; 

Proof state:
case h.h.mk
a b c d : ℝ
h : a * d - b * c = 1
h_denom :
  ∀ (z : ℍ), denom (toGLPos { val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) }) z ≠ 0
hc : c ≠ 0
z : ℂ
hz : 0 < z.im
⊢ { val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) } • { val := z, property := hz } =
    ((fun x => a / c +ᵥ x) ∘
        (fun x => ModularGroup.S • x) ∘
          (fun x => c * d +ᵥ x) ∘ fun x => { val := c * c, property := (_ : 0 < c * c) } • x)
      { val := z, property := hz }

Next tactic:
ext1
theorem exists_SL2_smul_eq_of_apply_zero_one_ne_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 ≠ 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v w : ℝ),
      (g • · : ℍ → ℍ) =
        (w +ᵥ ·) ∘ (ModularGroup.S • · : ℍ → ℍ) ∘ (v +ᵥ · : ℍ → ℍ) ∘ (u • · : ℍ → ℍ) := by
  have h_denom := denom_ne_zero g
  induction' g using Matrix.SpecialLinearGroup.fin_two_induction with a b c d h
  replace hc : c ≠ 0; · simpa using hc
  refine' ⟨⟨_, mul_self_pos.mpr hc⟩, c * d, a / c, _⟩
  ext1 ⟨z, hz⟩; ext1
  

Proof state:
case h.h.mk.h
a b c d : ℝ
h : a * d - b * c = 1
h_denom :
  ∀ (z : ℍ), denom (toGLPos { val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) }) z ≠ 0
hc : c ≠ 0
z : ℂ
hz : 0 < z.im
⊢ ↑({ val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) } •
        { val := z, property := hz }) =
    ↑(((fun x => a / c +ᵥ x) ∘
          (fun x => ModularGroup.S • x) ∘
            (fun x => c * d +ᵥ x) ∘ fun x => { val := c * c, property := (_ : 0 < c * c) } • x)
        { val := z, property := hz })

Next tactic:
suffices (↑a * z + b) / (↑c * z + d) = a / c - (c * d + ↑c * ↑c * z)⁻¹ by
    -- Porting note: golfed broken proof
    simpa only [modular_S_smul, inv_neg, Function.comp_apply, coe_vadd, Complex.ofReal_mul,
      coe_pos_real_smul, Complex.real_smul, Complex.ofReal_div, coe_mk]
theorem exists_SL2_smul_eq_of_apply_zero_one_ne_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 ≠ 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v w : ℝ),
      (g • · : ℍ → ℍ) =
        (w +ᵥ ·) ∘ (ModularGroup.S • · : ℍ → ℍ) ∘ (v +ᵥ · : ℍ → ℍ) ∘ (u • · : ℍ → ℍ) := by
  have h_denom := denom_ne_zero g
  induction' g using Matrix.SpecialLinearGroup.fin_two_induction with a b c d h
  replace hc : c ≠ 0; · simpa using hc
  refine' ⟨⟨_, mul_self_pos.mpr hc⟩, c * d, a / c, _⟩
  ext1 ⟨z, hz⟩; ext1
  suffices (↑a * z + b) / (↑c * z + d) = a / c - (c * d + ↑c * ↑c * z)⁻¹ by
    -- Porting note: golfed broken proof
    

Proof state:
a b c d : ℝ
h : a * d - b * c = 1
h_denom :
  ∀ (z : ℍ), denom (toGLPos { val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) }) z ≠ 0
hc : c ≠ 0
z : ℂ
hz : 0 < z.im
this : (↑a * z + ↑b) / (↑c * z + ↑d) = ↑a / ↑c - (↑c * ↑d + ↑c * ↑c * z)⁻¹
⊢ ↑({ val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) } •
        { val := z, property := hz }) =
    ↑(((fun x => a / c +ᵥ x) ∘
          (fun x => ModularGroup.S • x) ∘
            (fun x => c * d +ᵥ x) ∘ fun x => { val := c * c, property := (_ : 0 < c * c) } • x)
        { val := z, property := hz })

Next tactic:
simpa only [modular_S_smul, inv_neg, Function.comp_apply, coe_vadd, Complex.ofReal_mul,
      coe_pos_real_smul, Complex.real_smul, Complex.ofReal_div, coe_mk]
theorem exists_SL2_smul_eq_of_apply_zero_one_ne_zero (g : SL(2, ℝ)) (hc : ↑ₘ[ℝ] g 1 0 ≠ 0) :
    ∃ (u : { x : ℝ // 0 < x }) (v w : ℝ),
      (g • · : ℍ → ℍ) =
        (w +ᵥ ·) ∘ (ModularGroup.S • · : ℍ → ℍ) ∘ (v +ᵥ · : ℍ → ℍ) ∘ (u • · : ℍ → ℍ) := by
  have h_denom := denom_ne_zero g
  induction' g using Matrix.SpecialLinearGroup.fin_two_induction with a b c d h
  replace hc : c ≠ 0; · simpa using hc
  refine' ⟨⟨_, mul_self_pos.mpr hc⟩, c * d, a / c, _⟩
  ext1 ⟨z, hz⟩; ext1
  suffices (↑a * z + b) / (↑c * z + d) = a / c - (c * d + ↑c * ↑c * z)⁻¹ by
    -- Porting note: golfed broken proof
    simpa only [modular_S_smul, inv_neg, Function.comp_apply, coe_vadd, Complex.ofReal_mul,
      coe_pos_real_smul, Complex.real_smul, Complex.ofReal_div, coe_mk]
  

Proof state:
case h.h.mk.h
a b c d : ℝ
h : a * d - b * c = 1
h_denom :
  ∀ (z : ℍ), denom (toGLPos { val := of ![![a, b], ![c, d]], property := (_ : det (of ![![a, b], ![c, d]]) = 1) }) z ≠ 0
hc : c ≠ 0
z : ℂ
hz : 0 < z.im
⊢ (↑a * z + ↑b) / (↑c * z + ↑d) = ↑a / ↑c - (↑c * ↑d + ↑c * ↑c * z)⁻¹

Next tactic:
replace hc : (c : ℂ) ≠ 0