l3lab/ntp-mathlib huggingface dataset:
/-- From an upper bound on `sqrtTwoAddSeries 0 n = 2 cos (π / 2 ^ (n+1))` of the form
`sqrtTwoAddSeries 0 n ≤ 2 - (a / 2 ^ (n + 1)) ^ 2)`, one can deduce the lower bound `a < π`
thanks to basic trigonometric inequalities as expressed in `pi_gt_sqrtTwoAddSeries`. -/
theorem pi_lower_bound_start (n : ℕ) {a}
    (h : sqrtTwoAddSeries ((0 : ℕ) / (1 : ℕ)) n ≤ (2 : ℝ) - (a / (2 : ℝ) ^ (n + 1)) ^ 2) :
    a < π := by
  refine' lt_of_le_of_lt _ (pi_gt_sqrtTwoAddSeries n); rw [mul_comm]
  refine' (div_le_iff (pow_pos (by norm_num) _ : (0 : ℝ) < _)).mp (le_sqrt_of_sq_le _)
  rwa [le_sub_comm, show (0 : ℝ) = (0 : ℕ) / (1 : ℕ) by 

Proof state:
n : ℕ
a : ℝ
h : sqrtTwoAddSeries (↑0 / ↑1) n ≤ 2 - (a / 2 ^ (n + 1)) ^ 2
⊢ 0 = ↑0 / ↑1

Next tactic:
rw [Nat.cast_zero, zero_div]
theorem sqrtTwoAddSeries_step_up (c d : ℕ) {a b n : ℕ} {z : ℝ} (hz : sqrtTwoAddSeries (c / d) n ≤ z)
    (hb : 0 < b) (hd : 0 < d) (h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b) :
    sqrtTwoAddSeries (a / b) (n + 1) ≤ z := by
  

Proof state:
c d a b n : ℕ
z : ℝ
hz : sqrtTwoAddSeries (↑c / ↑d) n ≤ z
hb : 0 < b
hd : 0 < d
h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b
⊢ sqrtTwoAddSeries (↑a / ↑b) (n + 1) ≤ z

Next tactic:
refine' le_trans _ hz
theorem sqrtTwoAddSeries_step_up (c d : ℕ) {a b n : ℕ} {z : ℝ} (hz : sqrtTwoAddSeries (c / d) n ≤ z)
    (hb : 0 < b) (hd : 0 < d) (h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b) :
    sqrtTwoAddSeries (a / b) (n + 1) ≤ z := by
  refine' le_trans _ hz; 

Proof state:
c d a b n : ℕ
z : ℝ
hz : sqrtTwoAddSeries (↑c / ↑d) n ≤ z
hb : 0 < b
hd : 0 < d
h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b
⊢ sqrtTwoAddSeries (↑a / ↑b) (n + 1) ≤ sqrtTwoAddSeries (↑c / ↑d) n

Next tactic:
rw [sqrtTwoAddSeries_succ]
theorem sqrtTwoAddSeries_step_up (c d : ℕ) {a b n : ℕ} {z : ℝ} (hz : sqrtTwoAddSeries (c / d) n ≤ z)
    (hb : 0 < b) (hd : 0 < d) (h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b) :
    sqrtTwoAddSeries (a / b) (n + 1) ≤ z := by
  refine' le_trans _ hz; rw [sqrtTwoAddSeries_succ]; 

Proof state:
c d a b n : ℕ
z : ℝ
hz : sqrtTwoAddSeries (↑c / ↑d) n ≤ z
hb : 0 < b
hd : 0 < d
h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b
⊢ sqrtTwoAddSeries (sqrt (2 + ↑a / ↑b)) n ≤ sqrtTwoAddSeries (↑c / ↑d) n

Next tactic:
apply sqrtTwoAddSeries_monotone_left
theorem sqrtTwoAddSeries_step_up (c d : ℕ) {a b n : ℕ} {z : ℝ} (hz : sqrtTwoAddSeries (c / d) n ≤ z)
    (hb : 0 < b) (hd : 0 < d) (h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b) :
    sqrtTwoAddSeries (a / b) (n + 1) ≤ z := by
  refine' le_trans _ hz; rw [sqrtTwoAddSeries_succ]; apply sqrtTwoAddSeries_monotone_left
  

Proof state:
case h
c d a b n : ℕ
z : ℝ
hz : sqrtTwoAddSeries (↑c / ↑d) n ≤ z
hb : 0 < b
hd : 0 < d
h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b
⊢ sqrt (2 + ↑a / ↑b) ≤ ↑c / ↑d

Next tactic:
have hb' : 0 < (b : ℝ) := Nat.cast_pos.2 hb
theorem sqrtTwoAddSeries_step_up (c d : ℕ) {a b n : ℕ} {z : ℝ} (hz : sqrtTwoAddSeries (c / d) n ≤ z)
    (hb : 0 < b) (hd : 0 < d) (h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b) :
    sqrtTwoAddSeries (a / b) (n + 1) ≤ z := by
  refine' le_trans _ hz; rw [sqrtTwoAddSeries_succ]; apply sqrtTwoAddSeries_monotone_left
  have hb' : 0 < (b : ℝ) := Nat.cast_pos.2 hb
  

Proof state:
case h
c d a b n : ℕ
z : ℝ
hz : sqrtTwoAddSeries (↑c / ↑d) n ≤ z
hb : 0 < b
hd : 0 < d
h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b
hb' : 0 < ↑b
⊢ sqrt (2 + ↑a / ↑b) ≤ ↑c / ↑d

Next tactic:
have hd' : 0 < (d : ℝ) := Nat.cast_pos.2 hd
theorem sqrtTwoAddSeries_step_up (c d : ℕ) {a b n : ℕ} {z : ℝ} (hz : sqrtTwoAddSeries (c / d) n ≤ z)
    (hb : 0 < b) (hd : 0 < d) (h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b) :
    sqrtTwoAddSeries (a / b) (n + 1) ≤ z := by
  refine' le_trans _ hz; rw [sqrtTwoAddSeries_succ]; apply sqrtTwoAddSeries_monotone_left
  have hb' : 0 < (b : ℝ) := Nat.cast_pos.2 hb
  have hd' : 0 < (d : ℝ) := Nat.cast_pos.2 hd
  

Proof state:
case h
c d a b n : ℕ
z : ℝ
hz : sqrtTwoAddSeries (↑c / ↑d) n ≤ z
hb : 0 < b
hd : 0 < d
h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b
hb' : 0 < ↑b
hd' : 0 < ↑d
⊢ sqrt (2 + ↑a / ↑b) ≤ ↑c / ↑d

Next tactic:
rw [sqrt_le_left (div_nonneg c.cast_nonneg d.cast_nonneg), div_pow,
    add_div_eq_mul_add_div _ _ (ne_of_gt hb'), div_le_div_iff hb' (pow_pos hd' _)]
theorem sqrtTwoAddSeries_step_up (c d : ℕ) {a b n : ℕ} {z : ℝ} (hz : sqrtTwoAddSeries (c / d) n ≤ z)
    (hb : 0 < b) (hd : 0 < d) (h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b) :
    sqrtTwoAddSeries (a / b) (n + 1) ≤ z := by
  refine' le_trans _ hz; rw [sqrtTwoAddSeries_succ]; apply sqrtTwoAddSeries_monotone_left
  have hb' : 0 < (b : ℝ) := Nat.cast_pos.2 hb
  have hd' : 0 < (d : ℝ) := Nat.cast_pos.2 hd
  rw [sqrt_le_left (div_nonneg c.cast_nonneg d.cast_nonneg), div_pow,
    add_div_eq_mul_add_div _ _ (ne_of_gt hb'), div_le_div_iff hb' (pow_pos hd' _)]
  

Proof state:
case h
c d a b n : ℕ
z : ℝ
hz : sqrtTwoAddSeries (↑c / ↑d) n ≤ z
hb : 0 < b
hd : 0 < d
h : (2 * b + a) * d ^ 2 ≤ c ^ 2 * b
hb' : 0 < ↑b
hd' : 0 < ↑d
⊢ (2 * ↑b + ↑a) * ↑d ^ 2 ≤ ↑c ^ 2 * ↑b

Next tactic:
exact mod_cast h
/-- From a lower bound on `sqrtTwoAddSeries 0 n = 2 cos (π / 2 ^ (n+1))` of the form
`2 - ((a - 1 / 4 ^ n) / 2 ^ (n + 1)) ^ 2 ≤ sqrtTwoAddSeries 0 n`, one can deduce the upper bound
`π < a` thanks to basic trigonometric formulas as expressed in `pi_lt_sqrtTwoAddSeries`. -/
theorem pi_upper_bound_start (n : ℕ) {a}
    (h : (2 : ℝ) - ((a - 1 / (4 : ℝ) ^ n) / (2 : ℝ) ^ (n + 1)) ^ 2 ≤
        sqrtTwoAddSeries ((0 : ℕ) / (1 : ℕ)) n)
    (h₂ : (1 : ℝ) / (4 : ℝ) ^ n ≤ a) : π < a := by
  

Proof state:
n : ℕ
a : ℝ
h : 2 - ((a - 1 / 4 ^ n) / 2 ^ (n + 1)) ^ 2 ≤ sqrtTwoAddSeries (↑0 / ↑1) n
h₂ : 1 / 4 ^ n ≤ a
⊢ π < a

Next tactic:
refine' lt_of_lt_of_le (pi_lt_sqrtTwoAddSeries n) _
/-- From a lower bound on `sqrtTwoAddSeries 0 n = 2 cos (π / 2 ^ (n+1))` of the form
`2 - ((a - 1 / 4 ^ n) / 2 ^ (n + 1)) ^ 2 ≤ sqrtTwoAddSeries 0 n`, one can deduce the upper bound
`π < a` thanks to basic trigonometric formulas as expressed in `pi_lt_sqrtTwoAddSeries`. -/
theorem pi_upper_bound_start (n : ℕ) {a}
    (h : (2 : ℝ) - ((a - 1 / (4 : ℝ) ^ n) / (2 : ℝ) ^ (n + 1)) ^ 2 ≤
        sqrtTwoAddSeries ((0 : ℕ) / (1 : ℕ)) n)
    (h₂ : (1 : ℝ) / (4 : ℝ) ^ n ≤ a) : π < a := by
  refine' lt_of_lt_of_le (pi_lt_sqrtTwoAddSeries n) _
  

Proof state:
n : ℕ
a : ℝ
h : 2 - ((a - 1 / 4 ^ n) / 2 ^ (n + 1)) ^ 2 ≤ sqrtTwoAddSeries (↑0 / ↑1) n
h₂ : 1 / 4 ^ n ≤ a
⊢ 2 ^ (n + 1) * sqrt (2 - sqrtTwoAddSeries 0 n) + 1 / 4 ^ n ≤ a

Next tactic:
rw [← le_sub_iff_add_le, ← le_div_iff', sqrt_le_left, sub_le_comm]
/-- From a lower bound on `sqrtTwoAddSeries 0 n = 2 cos (π / 2 ^ (n+1))` of the form
`2 - ((a - 1 / 4 ^ n) / 2 ^ (n + 1)) ^ 2 ≤ sqrtTwoAddSeries 0 n`, one can deduce the upper bound
`π < a` thanks to basic trigonometric formulas as expressed in `pi_lt_sqrtTwoAddSeries`. -/
theorem pi_upper_bound_start (n : ℕ) {a}
    (h : (2 : ℝ) - ((a - 1 / (4 : ℝ) ^ n) / (2 : ℝ) ^ (n + 1)) ^ 2 ≤
        sqrtTwoAddSeries ((0 : ℕ) / (1 : ℕ)) n)
    (h₂ : (1 : ℝ) / (4 : ℝ) ^ n ≤ a) : π < a := by
  refine' lt_of_lt_of_le (pi_lt_sqrtTwoAddSeries n) _
  rw [← le_sub_iff_add_le, ← le_div_iff', sqrt_le_left, sub_le_comm]
  · 

Proof state:
n : ℕ
a : ℝ
h : 2 - ((a - 1 / 4 ^ n) / 2 ^ (n + 1)) ^ 2 ≤ sqrtTwoAddSeries (↑0 / ↑1) n
h₂ : 1 / 4 ^ n ≤ a
⊢ 2 - ((a - 1 / 4 ^ n) / 2 ^ (n + 1)) ^ 2 ≤ sqrtTwoAddSeries 0 n

Next tactic:
rwa [Nat.cast_zero, zero_div] at h
/-- From a lower bound on `sqrtTwoAddSeries 0 n = 2 cos (π / 2 ^ (n+1))` of the form
`2 - ((a - 1 / 4 ^ n) / 2 ^ (n + 1)) ^ 2 ≤ sqrtTwoAddSeries 0 n`, one can deduce the upper bound
`π < a` thanks to basic trigonometric formulas as expressed in `pi_lt_sqrtTwoAddSeries`. -/
theorem pi_upper_bound_start (n : ℕ) {a}
    (h : (2 : ℝ) - ((a - 1 / (4 : ℝ) ^ n) / (2 : ℝ) ^ (n + 1)) ^ 2 ≤
        sqrtTwoAddSeries ((0 : ℕ) / (1 : ℕ)) n)
    (h₂ : (1 : ℝ) / (4 : ℝ) ^ n ≤ a) : π < a := by
  refine' lt_of_lt_of_le (pi_lt_sqrtTwoAddSeries n) _
  rw [← le_sub_iff_add_le, ← le_div_iff', sqrt_le_left, sub_le_comm]
  · rwa [Nat.cast_zero, zero_div] at h
  · 

Proof state:
n : ℕ
a : ℝ
h : 2 - ((a - 1 / 4 ^ n) / 2 ^ (n + 1)) ^ 2 ≤ sqrtTwoAddSeries (↑0 / ↑1) n
h₂ : 1 / 4 ^ n ≤ a
⊢ 0 ≤ (a - 1 / 4 ^ n) / 2 ^ (n + 1)

Next tactic:
exact div_nonneg (sub_nonneg.2 h₂) (pow_nonneg (le_of_lt zero_lt_two) _)
/-- From a lower bound on `sqrtTwoAddSeries 0 n = 2 cos (π / 2 ^ (n+1))` of the form
`2 - ((a - 1 / 4 ^ n) / 2 ^ (n + 1)) ^ 2 ≤ sqrtTwoAddSeries 0 n`, one can deduce the upper bound
`π < a` thanks to basic trigonometric formulas as expressed in `pi_lt_sqrtTwoAddSeries`. -/
theorem pi_upper_bound_start (n : ℕ) {a}
    (h : (2 : ℝ) - ((a - 1 / (4 : ℝ) ^ n) / (2 : ℝ) ^ (n + 1)) ^ 2 ≤
        sqrtTwoAddSeries ((0 : ℕ) / (1 : ℕ)) n)
    (h₂ : (1 : ℝ) / (4 : ℝ) ^ n ≤ a) : π < a := by
  refine' lt_of_lt_of_le (pi_lt_sqrtTwoAddSeries n) _
  rw [← le_sub_iff_add_le, ← le_div_iff', sqrt_le_left, sub_le_comm]
  · rwa [Nat.cast_zero, zero_div] at h
  · exact div_nonneg (sub_nonneg.2 h₂) (pow_nonneg (le_of_lt zero_lt_two) _)
  · 

Proof state:
n : ℕ
a : ℝ
h : 2 - ((a - 1 / 4 ^ n) / 2 ^ (n + 1)) ^ 2 ≤ sqrtTwoAddSeries (↑0 / ↑1) n
h₂ : 1 / 4 ^ n ≤ a
⊢ 0 < 2 ^ (n + 1)

Next tactic:
exact pow_pos zero_lt_two _
theorem sqrtTwoAddSeries_step_down (a b : ℕ) {c d n : ℕ} {z : ℝ}
    (hz : z ≤ sqrtTwoAddSeries (a / b) n) (hb : 0 < b) (hd : 0 < d)
    (h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2) : z ≤ sqrtTwoAddSeries (c / d) (n + 1) := by
  

Proof state:
a b c d n : ℕ
z : ℝ
hz : z ≤ sqrtTwoAddSeries (↑a / ↑b) n
hb : 0 < b
hd : 0 < d
h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2
⊢ z ≤ sqrtTwoAddSeries (↑c / ↑d) (n + 1)

Next tactic:
apply le_trans hz
theorem sqrtTwoAddSeries_step_down (a b : ℕ) {c d n : ℕ} {z : ℝ}
    (hz : z ≤ sqrtTwoAddSeries (a / b) n) (hb : 0 < b) (hd : 0 < d)
    (h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2) : z ≤ sqrtTwoAddSeries (c / d) (n + 1) := by
  apply le_trans hz; 

Proof state:
a b c d n : ℕ
z : ℝ
hz : z ≤ sqrtTwoAddSeries (↑a / ↑b) n
hb : 0 < b
hd : 0 < d
h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2
⊢ sqrtTwoAddSeries (↑a / ↑b) n ≤ sqrtTwoAddSeries (↑c / ↑d) (n + 1)

Next tactic:
rw [sqrtTwoAddSeries_succ]
theorem sqrtTwoAddSeries_step_down (a b : ℕ) {c d n : ℕ} {z : ℝ}
    (hz : z ≤ sqrtTwoAddSeries (a / b) n) (hb : 0 < b) (hd : 0 < d)
    (h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2) : z ≤ sqrtTwoAddSeries (c / d) (n + 1) := by
  apply le_trans hz; rw [sqrtTwoAddSeries_succ]; 

Proof state:
a b c d n : ℕ
z : ℝ
hz : z ≤ sqrtTwoAddSeries (↑a / ↑b) n
hb : 0 < b
hd : 0 < d
h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2
⊢ sqrtTwoAddSeries (↑a / ↑b) n ≤ sqrtTwoAddSeries (sqrt (2 + ↑c / ↑d)) n

Next tactic:
apply sqrtTwoAddSeries_monotone_left
theorem sqrtTwoAddSeries_step_down (a b : ℕ) {c d n : ℕ} {z : ℝ}
    (hz : z ≤ sqrtTwoAddSeries (a / b) n) (hb : 0 < b) (hd : 0 < d)
    (h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2) : z ≤ sqrtTwoAddSeries (c / d) (n + 1) := by
  apply le_trans hz; rw [sqrtTwoAddSeries_succ]; apply sqrtTwoAddSeries_monotone_left
  

Proof state:
case h
a b c d n : ℕ
z : ℝ
hz : z ≤ sqrtTwoAddSeries (↑a / ↑b) n
hb : 0 < b
hd : 0 < d
h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2
⊢ ↑a / ↑b ≤ sqrt (2 + ↑c / ↑d)

Next tactic:
apply le_sqrt_of_sq_le
theorem sqrtTwoAddSeries_step_down (a b : ℕ) {c d n : ℕ} {z : ℝ}
    (hz : z ≤ sqrtTwoAddSeries (a / b) n) (hb : 0 < b) (hd : 0 < d)
    (h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2) : z ≤ sqrtTwoAddSeries (c / d) (n + 1) := by
  apply le_trans hz; rw [sqrtTwoAddSeries_succ]; apply sqrtTwoAddSeries_monotone_left
  apply le_sqrt_of_sq_le
  

Proof state:
case h.h
a b c d n : ℕ
z : ℝ
hz : z ≤ sqrtTwoAddSeries (↑a / ↑b) n
hb : 0 < b
hd : 0 < d
h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2
⊢ (↑a / ↑b) ^ 2 ≤ 2 + ↑c / ↑d

Next tactic:
have hb' : 0 < (b : ℝ) := Nat.cast_pos.2 hb
theorem sqrtTwoAddSeries_step_down (a b : ℕ) {c d n : ℕ} {z : ℝ}
    (hz : z ≤ sqrtTwoAddSeries (a / b) n) (hb : 0 < b) (hd : 0 < d)
    (h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2) : z ≤ sqrtTwoAddSeries (c / d) (n + 1) := by
  apply le_trans hz; rw [sqrtTwoAddSeries_succ]; apply sqrtTwoAddSeries_monotone_left
  apply le_sqrt_of_sq_le
  have hb' : 0 < (b : ℝ) := Nat.cast_pos.2 hb
  

Proof state:
case h.h
a b c d n : ℕ
z : ℝ
hz : z ≤ sqrtTwoAddSeries (↑a / ↑b) n
hb : 0 < b
hd : 0 < d
h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2
hb' : 0 < ↑b
⊢ (↑a / ↑b) ^ 2 ≤ 2 + ↑c / ↑d

Next tactic:
have hd' : 0 < (d : ℝ) := Nat.cast_pos.2 hd
theorem sqrtTwoAddSeries_step_down (a b : ℕ) {c d n : ℕ} {z : ℝ}
    (hz : z ≤ sqrtTwoAddSeries (a / b) n) (hb : 0 < b) (hd : 0 < d)
    (h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2) : z ≤ sqrtTwoAddSeries (c / d) (n + 1) := by
  apply le_trans hz; rw [sqrtTwoAddSeries_succ]; apply sqrtTwoAddSeries_monotone_left
  apply le_sqrt_of_sq_le
  have hb' : 0 < (b : ℝ) := Nat.cast_pos.2 hb
  have hd' : 0 < (d : ℝ) := Nat.cast_pos.2 hd
  

Proof state:
case h.h
a b c d n : ℕ
z : ℝ
hz : z ≤ sqrtTwoAddSeries (↑a / ↑b) n
hb : 0 < b
hd : 0 < d
h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2
hb' : 0 < ↑b
hd' : 0 < ↑d
⊢ (↑a / ↑b) ^ 2 ≤ 2 + ↑c / ↑d

Next tactic:
rw [div_pow, add_div_eq_mul_add_div _ _ (ne_of_gt hd'), div_le_div_iff (pow_pos hb' _) hd']
theorem sqrtTwoAddSeries_step_down (a b : ℕ) {c d n : ℕ} {z : ℝ}
    (hz : z ≤ sqrtTwoAddSeries (a / b) n) (hb : 0 < b) (hd : 0 < d)
    (h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2) : z ≤ sqrtTwoAddSeries (c / d) (n + 1) := by
  apply le_trans hz; rw [sqrtTwoAddSeries_succ]; apply sqrtTwoAddSeries_monotone_left
  apply le_sqrt_of_sq_le
  have hb' : 0 < (b : ℝ) := Nat.cast_pos.2 hb
  have hd' : 0 < (d : ℝ) := Nat.cast_pos.2 hd
  rw [div_pow, add_div_eq_mul_add_div _ _ (ne_of_gt hd'), div_le_div_iff (pow_pos hb' _) hd']
  

Proof state:
case h.h
a b c d n : ℕ
z : ℝ
hz : z ≤ sqrtTwoAddSeries (↑a / ↑b) n
hb : 0 < b
hd : 0 < d
h : a ^ 2 * d ≤ (2 * d + c) * b ^ 2
hb' : 0 < ↑b
hd' : 0 < ↑d
⊢ ↑a ^ 2 * ↑d ≤ (2 * ↑d + ↑c) * ↑b ^ 2

Next tactic:
exact mod_cast h
theorem pi_gt_three : 3 < π := by
  

Proof state:
⊢ 3 < π

Next tactic:
pi_lower_bound [23/16]
theorem pi_gt_314 : 3.14 < π := by
  

Proof state:
⊢ 3.14 < π

Next tactic:
pi_lower_bound [99 / 70, 874 / 473, 1940 / 989, 1447 / 727]
theorem pi_lt_315 : π < 3.15 := by
  

Proof state:
⊢ π < 3.15

Next tactic:
pi_upper_bound [140 / 99, 279 / 151, 51 / 26, 412 / 207]
theorem pi_gt_31415 : 3.1415 < π := by
  

Proof state:
⊢ 3.1415 < π

Next tactic:
pi_lower_bound
        [11482 / 8119, 5401 / 2923, 2348 / 1197, 11367 / 5711, 25705 / 12868, 23235 / 11621]
theorem pi_lt_31416 : π < 3.1416 := by
    

Proof state:
⊢ π < 3.1416

Next tactic:
pi_upper_bound
        [4756 / 3363, 101211 / 54775, 505534 / 257719, 83289 / 41846, 411278 / 205887,
          438142 / 219137, 451504 / 225769, 265603 / 132804, 849938 / 424971]
theorem pi_gt_3141592 : 3.141592 < π := by
    

Proof state:
⊢ 3.141592 < π

Next tactic:
pi_lower_bound
        [11482 / 8119, 7792 / 4217, 54055 / 27557, 949247 / 476920, 3310126 / 1657059,
          2635492 / 1318143, 1580265 / 790192, 1221775 / 610899, 3612247 / 1806132, 849943 / 424972]
theorem pi_lt_3141593 : π < 3.141593 := by
    

Proof state:
⊢ π < 3.141593

Next tactic:
pi_upper_bound
        [27720 / 19601, 56935 / 30813, 49359 / 25163, 258754 / 130003, 113599 / 56868,
          1101994 / 551163, 8671537 / 4336095, 3877807 / 1938940, 52483813 / 26242030,
          56946167 / 28473117, 23798415 / 11899211]
theorem isOpen_iff (U : Set 𝖣.glued) : IsOpen U ↔ ∀ i, IsOpen (𝖣.ι i ⁻¹' U) := by
  

Proof state:
D : GlueData
U : Set ↑(GlueData.glued D.toGlueData)
⊢ IsOpen U ↔ ∀ (i : D.J), IsOpen (⇑(GlueData.ι D.toGlueData i) ⁻¹' U)

Next tactic:
delta CategoryTheory.GlueData.ι
theorem isOpen_iff (U : Set 𝖣.glued) : IsOpen U ↔ ∀ i, IsOpen (𝖣.ι i ⁻¹' U) := by
  delta CategoryTheory.GlueData.ι
  

Proof state:
D : GlueData
U : Set ↑(GlueData.glued D.toGlueData)
⊢ IsOpen U ↔ ∀ (i : D.J), IsOpen (⇑(Multicoequalizer.π (GlueData.diagram D.toGlueData) i) ⁻¹' U)

Next tactic:
simp_rw [← Multicoequalizer.ι_sigmaπ 𝖣.diagram]
theorem isOpen_iff (U : Set 𝖣.glued) : IsOpen U ↔ ∀ i, IsOpen (𝖣.ι i ⁻¹' U) := by
  delta CategoryTheory.GlueData.ι
  simp_rw [← Multicoequalizer.ι_sigmaπ 𝖣.diagram]
  

Proof state:
D : GlueData
U : Set ↑(GlueData.glued D.toGlueData)
⊢ IsOpen U ↔
    ∀ (i : D.J),
      IsOpen
        (⇑(Sigma.ι (GlueData.diagram D.toGlueData).right i ≫
              Multicoequalizer.sigmaπ (GlueData.diagram D.toGlueData)) ⁻¹'
          U)

Next tactic:
rw [← (homeoOfIso (Multicoequalizer.isoCoequalizer 𝖣.diagram).symm).isOpen_preimage]
theorem isOpen_iff (U : Set 𝖣.glued) : IsOpen U ↔ ∀ i, IsOpen (𝖣.ι i ⁻¹' U) := by
  delta CategoryTheory.GlueData.ι
  simp_rw [← Multicoequalizer.ι_sigmaπ 𝖣.diagram]
  rw [← (homeoOfIso (Multicoequalizer.isoCoequalizer 𝖣.diagram).symm).isOpen_preimage]
  

Proof state:
D : GlueData
U : Set ↑(GlueData.glued D.toGlueData)
⊢ IsOpen (⇑(homeoOfIso (Multicoequalizer.isoCoequalizer (GlueData.diagram D.toGlueData)).symm) ⁻¹' U) ↔
    ∀ (i : D.J),
      IsOpen
        (⇑(Sigma.ι (GlueData.diagram D.toGlueData).right i ≫
              Multicoequalizer.sigmaπ (GlueData.diagram D.toGlueData)) ⁻¹'
          U)

Next tactic:
rw [coequalizer_isOpen_iff]
theorem isOpen_iff (U : Set 𝖣.glued) : IsOpen U ↔ ∀ i, IsOpen (𝖣.ι i ⁻¹' U) := by
  delta CategoryTheory.GlueData.ι
  simp_rw [← Multicoequalizer.ι_sigmaπ 𝖣.diagram]
  rw [← (homeoOfIso (Multicoequalizer.isoCoequalizer 𝖣.diagram).symm).isOpen_preimage]
  rw [coequalizer_isOpen_iff]
  

Proof state:
D : GlueData
U : Set ↑(GlueData.glued D.toGlueData)
⊢ IsOpen
      (⇑(colimit.ι
            (parallelPair (MultispanIndex.fstSigmaMap (GlueData.diagram D.toGlueData))
              (MultispanIndex.sndSigmaMap (GlueData.diagram D.toGlueData)))
            WalkingParallelPair.one) ⁻¹'
        (⇑(homeoOfIso (Multicoequalizer.isoCoequalizer (GlueData.diagram D.toGlueData)).symm) ⁻¹' U)) ↔
    ∀ (i : D.J),
      IsOpen
        (⇑(Sigma.ι (GlueData.diagram D.toGlueData).right i ≫
              Multicoequalizer.sigmaπ (GlueData.diagram D.toGlueData)) ⁻¹'
          U)

Next tactic:
dsimp only [GlueData.diagram_l, GlueData.diagram_left, GlueData.diagram_r, GlueData.diagram_right,
    parallelPair_obj_one]
theorem isOpen_iff (U : Set 𝖣.glued) : IsOpen U ↔ ∀ i, IsOpen (𝖣.ι i ⁻¹' U) := by
  delta CategoryTheory.GlueData.ι
  simp_rw [← Multicoequalizer.ι_sigmaπ 𝖣.diagram]
  rw [← (homeoOfIso (Multicoequalizer.isoCoequalizer 𝖣.diagram).symm).isOpen_preimage]
  rw [coequalizer_isOpen_iff]
  dsimp only [GlueData.diagram_l, GlueData.diagram_left, GlueData.diagram_r, GlueData.diagram_right,
    parallelPair_obj_one]
  

Proof state:
D : GlueData
U : Set ↑(GlueData.glued D.toGlueData)
⊢ IsOpen
      (⇑(colimit.ι
            (parallelPair (MultispanIndex.fstSigmaMap (GlueData.diagram D.toGlueData))
              (MultispanIndex.sndSigmaMap (GlueData.diagram D.toGlueData)))
            WalkingParallelPair.one) ⁻¹'
        (⇑(homeoOfIso (Multicoequalizer.isoCoequalizer (GlueData.diagram D.toGlueData)).symm) ⁻¹' U)) ↔
    ∀ (i : D.J), IsOpen (⇑(Sigma.ι D.U i ≫ Multicoequalizer.sigmaπ (GlueData.diagram D.toGlueData)) ⁻¹' U)

Next tactic:
rw [colimit_isOpen_iff.{_,u}]
theorem isOpen_iff (U : Set 𝖣.glued) : IsOpen U ↔ ∀ i, IsOpen (𝖣.ι i ⁻¹' U) := by
  delta CategoryTheory.GlueData.ι
  simp_rw [← Multicoequalizer.ι_sigmaπ 𝖣.diagram]
  rw [← (homeoOfIso (Multicoequalizer.isoCoequalizer 𝖣.diagram).symm).isOpen_preimage]
  rw [coequalizer_isOpen_iff]
  dsimp only [GlueData.diagram_l, GlueData.diagram_left, GlueData.diagram_r, GlueData.diagram_right,
    parallelPair_obj_one]
  rw [colimit_isOpen_iff.{_,u}]  -- porting note: changed `.{u}` to `.{_,u}`.  fun fact: the proof
                                 -- breaks down if this `rw` is merged with the `rw` above.
  

Proof state:
D : GlueData
U : Set ↑(GlueData.glued D.toGlueData)
⊢ (∀ (j : Discrete D.J),
      IsOpen
        (⇑(colimit.ι (Discrete.functor D.U) j) ⁻¹'
          (⇑(colimit.ι
                (parallelPair (MultispanIndex.fstSigmaMap (GlueData.diagram D.toGlueData))
                  (MultispanIndex.sndSigmaMap (GlueData.diagram D.toGlueData)))
                WalkingParallelPair.one) ⁻¹'
            (⇑(homeoOfIso (Multicoequalizer.isoCoequalizer (GlueData.diagram D.toGlueData)).symm) ⁻¹' U)))) ↔
    ∀ (i : D.J), IsOpen (⇑(Sigma.ι D.U i ≫ Multicoequalizer.sigmaπ (GlueData.diagram D.toGlueData)) ⁻¹' U)

Next tactic:
constructor
theorem isOpen_iff (U : Set 𝖣.glued) : IsOpen U ↔ ∀ i, IsOpen (𝖣.ι i ⁻¹' U) := by
  delta CategoryTheory.GlueData.ι
  simp_rw [← Multicoequalizer.ι_sigmaπ 𝖣.diagram]
  rw [← (homeoOfIso (Multicoequalizer.isoCoequalizer 𝖣.diagram).symm).isOpen_preimage]
  rw [coequalizer_isOpen_iff]
  dsimp only [GlueData.diagram_l, GlueData.diagram_left, GlueData.diagram_r, GlueData.diagram_right,
    parallelPair_obj_one]
  rw [colimit_isOpen_iff.{_,u}]  -- porting note: changed `.{u}` to `.{_,u}`.  fun fact: the proof
                                 -- breaks down if this `rw` is merged with the `rw` above.
  constructor
  · 

Proof state:
case mp
D : GlueData
U : Set ↑(GlueData.glued D.toGlueData)
⊢ (∀ (j : Discrete D.J),
      IsOpen
        (⇑(colimit.ι (Discrete.functor D.U) j) ⁻¹'
          (⇑(colimit.ι
                (parallelPair (MultispanIndex.fstSigmaMap (GlueData.diagram D.toGlueData))
                  (MultispanIndex.sndSigmaMap (GlueData.diagram D.toGlueData)))
                WalkingParallelPair.one) ⁻¹'
            (⇑(homeoOfIso (Multicoequalizer.isoCoequalizer (GlueData.diagram D.toGlueData)).symm) ⁻¹' U)))) →
    ∀ (i : D.J), IsOpen (⇑(Sigma.ι D.U i ≫ Multicoequalizer.sigmaπ (GlueData.diagram D.toGlueData)) ⁻¹' U)

Next tactic:
intro h j
theorem isOpen_iff (U : Set 𝖣.glued) : IsOpen U ↔ ∀ i, IsOpen (𝖣.ι i ⁻¹' U) := by
  delta CategoryTheory.GlueData.ι
  simp_rw [← Multicoequalizer.ι_sigmaπ 𝖣.diagram]
  rw [← (homeoOfIso (Multicoequalizer.isoCoequalizer 𝖣.diagram).symm).isOpen_preimage]
  rw [coequalizer_isOpen_iff]
  dsimp only [GlueData.diagram_l, GlueData.diagram_left, GlueData.diagram_r, GlueData.diagram_right,
    parallelPair_obj_one]
  rw [colimit_isOpen_iff.{_,u}]  -- porting note: changed `.{u}` to `.{_,u}`.  fun fact: the proof
                                 -- breaks down if this `rw` is merged with the `rw` above.
  constructor
  · intro h j; 

Proof state:
case mp
D : GlueData
U : Set ↑(GlueData.glued D.toGlueData)
h :
  ∀ (j : Discrete D.J),
    IsOpen
      (⇑(colimit.ι (Discrete.functor D.U) j) ⁻¹'
        (⇑(colimit.ι
              (parallelPair (MultispanIndex.fstSigmaMap (GlueData.diagram D.toGlueData))
                (MultispanIndex.sndSigmaMap (GlueData.diagram D.toGlueData)))
              WalkingParallelPair.one) ⁻¹'
          (⇑(homeoOfIso (Multicoequalizer.isoCoequalizer (GlueData.diagram D.toGlueData)).symm) ⁻¹' U)))
j : D.J
⊢ IsOpen (⇑(Sigma.ι D.U j ≫ Multicoequalizer.sigmaπ (GlueData.diagram D.toGlueData)) ⁻¹' U)

Next tactic:
exact h ⟨j⟩
theorem isOpen_iff (U : Set 𝖣.glued) : IsOpen U ↔ ∀ i, IsOpen (𝖣.ι i ⁻¹' U) := by
  delta CategoryTheory.GlueData.ι
  simp_rw [← Multicoequalizer.ι_sigmaπ 𝖣.diagram]
  rw [← (homeoOfIso (Multicoequalizer.isoCoequalizer 𝖣.diagram).symm).isOpen_preimage]
  rw [coequalizer_isOpen_iff]
  dsimp only [GlueData.diagram_l, GlueData.diagram_left, GlueData.diagram_r, GlueData.diagram_right,
    parallelPair_obj_one]
  rw [colimit_isOpen_iff.{_,u}]  -- porting note: changed `.{u}` to `.{_,u}`.  fun fact: the proof
                                 -- breaks down if this `rw` is merged with the `rw` above.
  constructor
  · intro h j; exact h ⟨j⟩
  · 

Proof state:
case mpr
D : GlueData
U : Set ↑(GlueData.glued D.toGlueData)
⊢ (∀ (i : D.J), IsOpen (⇑(Sigma.ι D.U i ≫ Multicoequalizer.sigmaπ (GlueData.diagram D.toGlueData)) ⁻¹' U)) →
    ∀ (j : Discrete D.J),
      IsOpen
        (⇑(colimit.ι (Discrete.functor D.U) j) ⁻¹'
          (⇑(colimit.ι
                (parallelPair (MultispanIndex.fstSigmaMap (GlueData.diagram D.toGlueData))
                  (MultispanIndex.sndSigmaMap (GlueData.diagram D.toGlueData)))
                WalkingParallelPair.one) ⁻¹'
            (⇑(homeoOfIso (Multicoequalizer.isoCoequalizer (GlueData.diagram D.toGlueData)).symm) ⁻¹' U)))

Next tactic:
intro h j