Theorem: UpperHalfPlane.ModularGroup_T_zpow_mem_verticalStrip
File: Mathlib/Analysis/Complex/UpperHalfPlane/Topology.lean

tactic: let n := Int.floor (z.re/N)
state_before: z : ℍ
N : ℕ
hn : 0 < N
⊢ ∃ n, ModularGroup.T ^ (↑N * n) • z ∈ verticalStrip (↑N) z.im
state_after: z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
⊢ ∃ n, ModularGroup.T ^ (↑N * n) • z ∈ verticalStrip (↑N) z.im

tactic: use -n
state_before: z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
⊢ ∃ n, ModularGroup.T ^ (↑N * n) • z ∈ verticalStrip (↑N) z.im
state_after: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
⊢ ModularGroup.T ^ (↑N * -n) • z ∈ verticalStrip (↑N) z.im

tactic: rw [modular_T_zpow_smul z (N * -n)]
state_before: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
⊢ ModularGroup.T ^ (↑N * -n) • z ∈ verticalStrip (↑N) z.im
state_after: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
⊢ ↑(↑N * -n) +ᵥ z ∈ verticalStrip (↑N) z.im

tactic: refine ⟨?_, (by simp only [mul_neg, Int.cast_neg, Int.cast_mul, Int.cast_natCast, vadd_im,
  le_refl])⟩
state_before: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
⊢ ↑(↑N * -n) +ᵥ z ∈ verticalStrip (↑N) z.im
state_after: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
⊢ |(↑(↑N * -n) +ᵥ z).re| ≤ ↑N

tactic: have h : (N * (-n : ℝ) +ᵥ z).re = -N * Int.floor (z.re / N) + z.re := by
  simp only [Int.cast_natCast, mul_neg, vadd_re, neg_mul]
state_before: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
⊢ |(↑(↑N * -n) +ᵥ z).re| ≤ ↑N
state_after: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑N * -↑n +ᵥ z).re = -↑N * ↑⌊z.re / ↑N⌋ + z.re
⊢ |(↑(↑N * -n) +ᵥ z).re| ≤ ↑N

tactic: norm_cast at *
state_before: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑N * -↑n +ᵥ z).re = -↑N * ↑⌊z.re / ↑N⌋ + z.re
⊢ |(↑(↑N * -n) +ᵥ z).re| ≤ ↑N
state_after: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
⊢ |(↑(↑N * -n) +ᵥ z).re| ≤ ↑N

tactic: rw [h, add_comm]
state_before: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
⊢ |(↑(↑N * -n) +ᵥ z).re| ≤ ↑N
state_after: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
⊢ |z.re + ↑(-↑N * ⌊z.re / ↑N⌋)| ≤ ↑N

tactic: simp only [neg_mul, Int.cast_neg, Int.cast_mul, Int.cast_natCast, ge_iff_le]
state_before: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
⊢ |z.re + ↑(-↑N * ⌊z.re / ↑N⌋)| ≤ ↑N
state_after: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
⊢ |z.re + -(↑N * ↑⌊z.re / ↑N⌋)| ≤ ↑N

tactic: have hnn : (0 : ℝ) < (N : ℝ) := by norm_cast at *
state_before: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
⊢ |z.re + -(↑N * ↑⌊z.re / ↑N⌋)| ≤ ↑N
state_after: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
hnn : 0 < ↑N
⊢ |z.re + -(↑N * ↑⌊z.re / ↑N⌋)| ≤ ↑N

tactic: have h2 : z.re + -(N * n) =  z.re - n * N := by ring
state_before: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
hnn : 0 < ↑N
⊢ |z.re + -(↑N * ↑⌊z.re / ↑N⌋)| ≤ ↑N
state_after: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
hnn : 0 < ↑N
h2 : z.re + -(↑N * ↑n) = z.re - ↑n * ↑N
⊢ |z.re + -(↑N * ↑⌊z.re / ↑N⌋)| ≤ ↑N

tactic: rw [h2, abs_eq_self.2 (Int.sub_floor_div_mul_nonneg (z.re : ℝ) hnn)]
state_before: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
hnn : 0 < ↑N
h2 : z.re + -(↑N * ↑n) = z.re - ↑n * ↑N
⊢ |z.re + -(↑N * ↑⌊z.re / ↑N⌋)| ≤ ↑N
state_after: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
hnn : 0 < ↑N
h2 : z.re + -(↑N * ↑n) = z.re - ↑n * ↑N
⊢ z.re - ↑⌊z.re / ↑N⌋ * ↑N ≤ ↑N

tactic: apply (Int.sub_floor_div_mul_lt (z.re : ℝ) hnn).le
state_before: case h
z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
hnn : 0 < ↑N
h2 : z.re + -(↑N * ↑n) = z.re - ↑n * ↑N
⊢ z.re - ↑⌊z.re / ↑N⌋ * ↑N ≤ ↑N
state_after: no goals

tactic: simp only [mul_neg, Int.cast_neg, Int.cast_mul, Int.cast_natCast, vadd_im,
le_refl]
state_before: z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
⊢ z.im ≤ (↑(↑N * -n) +ᵥ z).im
state_after: no goals

tactic: simp only [Int.cast_natCast, mul_neg, vadd_re, neg_mul]
state_before: z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
⊢ (↑N * -↑n +ᵥ z).re = -↑N * ↑⌊z.re / ↑N⌋ + z.re
state_after: no goals

tactic: norm_cast at *
state_before: z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
⊢ 0 < ↑N
state_after: no goals

tactic: ring
state_before: z : ℍ
N : ℕ
hn : 0 < N
n : ℤ := ⌊z.re / ↑N⌋
h : (↑(↑N * -n) +ᵥ z).re = ↑(-↑N * ⌊z.re / ↑N⌋) + z.re
hnn : 0 < ↑N
⊢ z.re + -(↑N * ↑n) = z.re - ↑n * ↑N
state_after: no goals