l3lab/ntp-mathlib huggingface dataset:
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  

Proof state:
case pos
a b c d : ℕ
hb : b = 0
⊢ a / b * (c / d) ≤ a * c / (b * d)
case neg a b c d : ℕ hb : ¬b = 0 ⊢ a / b * (c / d) ≤ a * c / (b * d)

Next tactic:
case pos => simp [hb]
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  

Proof state:
a b c d : ℕ
hb : b = 0
⊢ a / b * (c / d) ≤ a * c / (b * d)

Next tactic:
case pos => simp [hb]
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => 

Proof state:
a b c d : ℕ
hb : b = 0
⊢ a / b * (c / d) ≤ a * c / (b * d)

Next tactic:
simp [hb]
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => simp [hb]
  

Proof state:
case neg
a b c d : ℕ
hb : ¬b = 0
⊢ a / b * (c / d) ≤ a * c / (b * d)

Next tactic:
by_cases hd : d = 0
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => simp [hb]
  by_cases hd : d = 0
  

Proof state:
case pos
a b c d : ℕ
hb : ¬b = 0
hd : d = 0
⊢ a / b * (c / d) ≤ a * c / (b * d)
case neg a b c d : ℕ hb : ¬b = 0 hd : ¬d = 0 ⊢ a / b * (c / d) ≤ a * c / (b * d)

Next tactic:
case pos => simp [hd]
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => simp [hb]
  by_cases hd : d = 0
  

Proof state:
a b c d : ℕ
hb : ¬b = 0
hd : d = 0
⊢ a / b * (c / d) ≤ a * c / (b * d)

Next tactic:
case pos => simp [hd]
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => simp [hb]
  by_cases hd : d = 0
  case pos => 

Proof state:
a b c d : ℕ
hb : ¬b = 0
hd : d = 0
⊢ a / b * (c / d) ≤ a * c / (b * d)

Next tactic:
simp [hd]
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => simp [hb]
  by_cases hd : d = 0
  case pos => simp [hd]
  

Proof state:
case neg
a b c d : ℕ
hb : ¬b = 0
hd : ¬d = 0
⊢ a / b * (c / d) ≤ a * c / (b * d)

Next tactic:
have hbd : b * d ≠ 0 := mul_ne_zero hb hd
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => simp [hb]
  by_cases hd : d = 0
  case pos => simp [hd]
  have hbd : b * d ≠ 0 := mul_ne_zero hb hd
  

Proof state:
case neg
a b c d : ℕ
hb : ¬b = 0
hd : ¬d = 0
hbd : b * d ≠ 0
⊢ a / b * (c / d) ≤ a * c / (b * d)

Next tactic:
rw [le_div_iff_mul_le (Nat.pos_of_ne_zero hbd)]
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => simp [hb]
  by_cases hd : d = 0
  case pos => simp [hd]
  have hbd : b * d ≠ 0 := mul_ne_zero hb hd
  rw [le_div_iff_mul_le (Nat.pos_of_ne_zero hbd)]
  

Proof state:
case neg
a b c d : ℕ
hb : ¬b = 0
hd : ¬d = 0
hbd : b * d ≠ 0
⊢ a / b * (c / d) * (b * d) ≤ a * c

Next tactic:
transitivity ((a / b) * b) * ((c / d) * d)
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => simp [hb]
  by_cases hd : d = 0
  case pos => simp [hd]
  have hbd : b * d ≠ 0 := mul_ne_zero hb hd
  rw [le_div_iff_mul_le (Nat.pos_of_ne_zero hbd)]
  transitivity ((a / b) * b) * ((c / d) * d)
  · 

Proof state:
case neg.a
a b c d : ℕ
hb : ¬b = 0
hd : ¬d = 0
hbd : b * d ≠ 0
⊢ a / b * (c / d) * (b * d) ≤ a / b * b * (c / d * d)

Next tactic:
apply le_of_eq
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => simp [hb]
  by_cases hd : d = 0
  case pos => simp [hd]
  have hbd : b * d ≠ 0 := mul_ne_zero hb hd
  rw [le_div_iff_mul_le (Nat.pos_of_ne_zero hbd)]
  transitivity ((a / b) * b) * ((c / d) * d)
  · apply le_of_eq; 

Proof state:
case neg.a.a
a b c d : ℕ
hb : ¬b = 0
hd : ¬d = 0
hbd : b * d ≠ 0
⊢ a / b * (c / d) * (b * d) = a / b * b * (c / d * d)

Next tactic:
simp only [mul_assoc, mul_left_comm]
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => simp [hb]
  by_cases hd : d = 0
  case pos => simp [hd]
  have hbd : b * d ≠ 0 := mul_ne_zero hb hd
  rw [le_div_iff_mul_le (Nat.pos_of_ne_zero hbd)]
  transitivity ((a / b) * b) * ((c / d) * d)
  · apply le_of_eq; simp only [mul_assoc, mul_left_comm]
  · 

Proof state:
case neg.a
a b c d : ℕ
hb : ¬b = 0
hd : ¬d = 0
hbd : b * d ≠ 0
⊢ a / b * b * (c / d * d) ≤ a * c

Next tactic:
apply Nat.mul_le_mul
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => simp [hb]
  by_cases hd : d = 0
  case pos => simp [hd]
  have hbd : b * d ≠ 0 := mul_ne_zero hb hd
  rw [le_div_iff_mul_le (Nat.pos_of_ne_zero hbd)]
  transitivity ((a / b) * b) * ((c / d) * d)
  · apply le_of_eq; simp only [mul_assoc, mul_left_comm]
  · apply Nat.mul_le_mul <;> 

Proof state:
case neg.a.h₁
a b c d : ℕ
hb : ¬b = 0
hd : ¬d = 0
hbd : b * d ≠ 0
⊢ a / b * b ≤ a

Next tactic:
apply div_mul_le_self
protected lemma div_mul_div_le (a b c d : ℕ) :
    (a / b) * (c / d) ≤ (a * c) / (b * d) := by
  by_cases hb : b = 0
  case pos => simp [hb]
  by_cases hd : d = 0
  case pos => simp [hd]
  have hbd : b * d ≠ 0 := mul_ne_zero hb hd
  rw [le_div_iff_mul_le (Nat.pos_of_ne_zero hbd)]
  transitivity ((a / b) * b) * ((c / d) * d)
  · apply le_of_eq; simp only [mul_assoc, mul_left_comm]
  · apply Nat.mul_le_mul <;> 

Proof state:
case neg.a.h₂
a b c d : ℕ
hb : ¬b = 0
hd : ¬d = 0
hbd : b * d ≠ 0
⊢ c / d * d ≤ c

Next tactic:
apply div_mul_le_self
private lemma iter_fp_bound (n k : ℕ) :
    let iter_next (n guess : ℕ) := (guess + n / guess) / 2;
    sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by
  

Proof state:
n k : ℕ
⊢ let iter_next := fun n guess => (guess + n / guess) / 2;
  sqrt.iter n k ≤ iter_next n (sqrt.iter n k)

Next tactic:
intro iter_next
private lemma iter_fp_bound (n k : ℕ) :
    let iter_next (n guess : ℕ) := (guess + n / guess) / 2;
    sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by
  intro iter_next
  

Proof state:
n k : ℕ
iter_next : ℕ → ℕ → ℕ := fun n guess => (guess + n / guess) / 2
⊢ sqrt.iter n k ≤ iter_next n (sqrt.iter n k)

Next tactic:
unfold sqrt.iter
private lemma iter_fp_bound (n k : ℕ) :
    let iter_next (n guess : ℕ) := (guess + n / guess) / 2;
    sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by
  intro iter_next
  unfold sqrt.iter
  

Proof state:
n k : ℕ
iter_next : ℕ → ℕ → ℕ := fun n guess => (guess + n / guess) / 2
⊢ (let next := (k + n / k) / 2;
    if _h : next < k then sqrt.iter n next else k) ≤
    iter_next n
      (let next := (k + n / k) / 2;
      if _h : next < k then sqrt.iter n next else k)

Next tactic:
by_cases h : (k + n / k) / 2 < k
private lemma iter_fp_bound (n k : ℕ) :
    let iter_next (n guess : ℕ) := (guess + n / guess) / 2;
    sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by
  intro iter_next
  unfold sqrt.iter
  by_cases h : (k + n / k) / 2 < k
  

Proof state:
case pos
n k : ℕ
iter_next : ℕ → ℕ → ℕ := fun n guess => (guess + n / guess) / 2
h : (k + n / k) / 2 < k
⊢ (let next := (k + n / k) / 2;
    if _h : next < k then sqrt.iter n next else k) ≤
    iter_next n
      (let next := (k + n / k) / 2;
      if _h : next < k then sqrt.iter n next else k)
case neg
n k : ℕ
iter_next : ℕ → ℕ → ℕ := fun n guess => (guess + n / guess) / 2
h : ¬(k + n / k) / 2 < k
⊢ (let next := (k + n / k) / 2;
    if _h : next < k then sqrt.iter n next else k) ≤
    iter_next n
      (let next := (k + n / k) / 2;
      if _h : next < k then sqrt.iter n next else k)

Next tactic:
case pos => simp [if_pos h]; exact iter_fp_bound _ _
private lemma iter_fp_bound (n k : ℕ) :
    let iter_next (n guess : ℕ) := (guess + n / guess) / 2;
    sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by
  intro iter_next
  unfold sqrt.iter
  by_cases h : (k + n / k) / 2 < k
  

Proof state:
n k : ℕ
iter_next : ℕ → ℕ → ℕ := fun n guess => (guess + n / guess) / 2
h : (k + n / k) / 2 < k
⊢ (let next := (k + n / k) / 2;
    if _h : next < k then sqrt.iter n next else k) ≤
    iter_next n
      (let next := (k + n / k) / 2;
      if _h : next < k then sqrt.iter n next else k)

Next tactic:
case pos => simp [if_pos h]; exact iter_fp_bound _ _
private lemma iter_fp_bound (n k : ℕ) :
    let iter_next (n guess : ℕ) := (guess + n / guess) / 2;
    sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by
  intro iter_next
  unfold sqrt.iter
  by_cases h : (k + n / k) / 2 < k
  case pos => 

Proof state:
n k : ℕ
iter_next : ℕ → ℕ → ℕ := fun n guess => (guess + n / guess) / 2
h : (k + n / k) / 2 < k
⊢ (let next := (k + n / k) / 2;
    if _h : next < k then sqrt.iter n next else k) ≤
    iter_next n
      (let next := (k + n / k) / 2;
      if _h : next < k then sqrt.iter n next else k)

Next tactic:
simp [if_pos h]
private lemma iter_fp_bound (n k : ℕ) :
    let iter_next (n guess : ℕ) := (guess + n / guess) / 2;
    sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by
  intro iter_next
  unfold sqrt.iter
  by_cases h : (k + n / k) / 2 < k
  case pos => simp [if_pos h]; 

Proof state:
n k : ℕ
iter_next : ℕ → ℕ → ℕ := fun n guess => (guess + n / guess) / 2
h : (k + n / k) / 2 < k
⊢ sqrt.iter n ((k + n / k) / 2) ≤ (sqrt.iter n ((k + n / k) / 2) + n / sqrt.iter n ((k + n / k) / 2)) / 2

Next tactic:
exact iter_fp_bound _ _
private lemma iter_fp_bound (n k : ℕ) :
    let iter_next (n guess : ℕ) := (guess + n / guess) / 2;
    sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by
  intro iter_next
  unfold sqrt.iter
  by_cases h : (k + n / k) / 2 < k
  case pos => simp [if_pos h]; exact iter_fp_bound _ _
  

Proof state:
case neg
n k : ℕ
iter_next : ℕ → ℕ → ℕ := fun n guess => (guess + n / guess) / 2
h : ¬(k + n / k) / 2 < k
⊢ (let next := (k + n / k) / 2;
    if _h : next < k then sqrt.iter n next else k) ≤
    iter_next n
      (let next := (k + n / k) / 2;
      if _h : next < k then sqrt.iter n next else k)

Next tactic:
case neg => simp [if_neg h]; exact Nat.le_of_not_lt h
private lemma iter_fp_bound (n k : ℕ) :
    let iter_next (n guess : ℕ) := (guess + n / guess) / 2;
    sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by
  intro iter_next
  unfold sqrt.iter
  by_cases h : (k + n / k) / 2 < k
  case pos => simp [if_pos h]; exact iter_fp_bound _ _
  

Proof state:
n k : ℕ
iter_next : ℕ → ℕ → ℕ := fun n guess => (guess + n / guess) / 2
h : ¬(k + n / k) / 2 < k
⊢ (let next := (k + n / k) / 2;
    if _h : next < k then sqrt.iter n next else k) ≤
    iter_next n
      (let next := (k + n / k) / 2;
      if _h : next < k then sqrt.iter n next else k)

Next tactic:
case neg => simp [if_neg h]; exact Nat.le_of_not_lt h
private lemma iter_fp_bound (n k : ℕ) :
    let iter_next (n guess : ℕ) := (guess + n / guess) / 2;
    sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by
  intro iter_next
  unfold sqrt.iter
  by_cases h : (k + n / k) / 2 < k
  case pos => simp [if_pos h]; exact iter_fp_bound _ _
  case neg => 

Proof state:
n k : ℕ
iter_next : ℕ → ℕ → ℕ := fun n guess => (guess + n / guess) / 2
h : ¬(k + n / k) / 2 < k
⊢ (let next := (k + n / k) / 2;
    if _h : next < k then sqrt.iter n next else k) ≤
    iter_next n
      (let next := (k + n / k) / 2;
      if _h : next < k then sqrt.iter n next else k)

Next tactic:
simp [if_neg h]
private lemma iter_fp_bound (n k : ℕ) :
    let iter_next (n guess : ℕ) := (guess + n / guess) / 2;
    sqrt.iter n k ≤ iter_next n (sqrt.iter n k) := by
  intro iter_next
  unfold sqrt.iter
  by_cases h : (k + n / k) / 2 < k
  case pos => simp [if_pos h]; exact iter_fp_bound _ _
  case neg => simp [if_neg h]; 

Proof state:
n k : ℕ
iter_next : ℕ → ℕ → ℕ := fun n guess => (guess + n / guess) / 2
h : ¬(k + n / k) / 2 < k
⊢ k ≤ (k + n / k) / 2

Next tactic:
exact Nat.le_of_not_lt h
private lemma AM_GM : {a b : ℕ} → (4 * a * b ≤ (a + b) * (a + b))
  | 0, _ => by 

Proof state:
x✝ : ℕ
⊢ 4 * 0 * x✝ ≤ (0 + x✝) * (0 + x✝)

Next tactic:
rw [mul_zero, zero_mul]
private lemma AM_GM : {a b : ℕ} → (4 * a * b ≤ (a + b) * (a + b))
  | 0, _ => by rw [mul_zero, zero_mul]; 

Proof state:
x✝ : ℕ
⊢ 0 ≤ (0 + x✝) * (0 + x✝)

Next tactic:
exact zero_le _
private lemma AM_GM : {a b : ℕ} → (4 * a * b ≤ (a + b) * (a + b))
  | 0, _ => by rw [mul_zero, zero_mul]; exact zero_le _
  | _, 0 => by 

Proof state:
x✝ : ℕ
⊢ 4 * x✝ * 0 ≤ (x✝ + 0) * (x✝ + 0)

Next tactic:
rw [mul_zero]
private lemma AM_GM : {a b : ℕ} → (4 * a * b ≤ (a + b) * (a + b))
  | 0, _ => by rw [mul_zero, zero_mul]; exact zero_le _
  | _, 0 => by rw [mul_zero]; 

Proof state:
x✝ : ℕ
⊢ 0 ≤ (x✝ + 0) * (x✝ + 0)

Next tactic:
exact zero_le _
private lemma AM_GM : {a b : ℕ} → (4 * a * b ≤ (a + b) * (a + b))
  | 0, _ => by rw [mul_zero, zero_mul]; exact zero_le _
  | _, 0 => by rw [mul_zero]; exact zero_le _
  | a + 1, b + 1 => by
    

Proof state:
a b : ℕ
⊢ 4 * (a + 1) * (b + 1) ≤ (a + 1 + (b + 1)) * (a + 1 + (b + 1))

Next tactic:
have ih := add_le_add_right (@AM_GM a b) 4
private lemma AM_GM : {a b : ℕ} → (4 * a * b ≤ (a + b) * (a + b))
  | 0, _ => by rw [mul_zero, zero_mul]; exact zero_le _
  | _, 0 => by rw [mul_zero]; exact zero_le _
  | a + 1, b + 1 => by
    have ih := add_le_add_right (@AM_GM a b) 4
    

Proof state:
a b : ℕ
ih : 4 * a * b + 4 ≤ (a + b) * (a + b) + 4
⊢ 4 * (a + 1) * (b + 1) ≤ (a + 1 + (b + 1)) * (a + 1 + (b + 1))

Next tactic:
simp only [mul_add, add_mul, show (4 : ℕ) = 1 + 1 + 1 + 1 from rfl, one_mul, mul_one] at ih ⊢
private lemma AM_GM : {a b : ℕ} → (4 * a * b ≤ (a + b) * (a + b))
  | 0, _ => by rw [mul_zero, zero_mul]; exact zero_le _
  | _, 0 => by rw [mul_zero]; exact zero_le _
  | a + 1, b + 1 => by
    have ih := add_le_add_right (@AM_GM a b) 4
    simp only [mul_add, add_mul, show (4 : ℕ) = 1 + 1 + 1 + 1 from rfl, one_mul, mul_one] at ih ⊢
    

Proof state:
a b : ℕ
ih : a * b + a * b + a * b + a * b + (1 + 1 + 1 + 1) ≤ a * a + b * a + (a * b + b * b) + (1 + 1 + 1 + 1)
⊢ a * b + a * b + a * b + a * b + (b + b + b + b) + (a + a + a + a + (1 + 1 + 1 + 1)) ≤
    a * a + a + (b * a + a) + (a + 1 + (b + 1)) + (a * b + b + (b * b + b) + (a + 1 + (b + 1)))

Next tactic:
simp only [add_assoc, add_left_comm, add_le_add_iff_left] at ih ⊢
private lemma AM_GM : {a b : ℕ} → (4 * a * b ≤ (a + b) * (a + b))
  | 0, _ => by rw [mul_zero, zero_mul]; exact zero_le _
  | _, 0 => by rw [mul_zero]; exact zero_le _
  | a + 1, b + 1 => by
    have ih := add_le_add_right (@AM_GM a b) 4
    simp only [mul_add, add_mul, show (4 : ℕ) = 1 + 1 + 1 + 1 from rfl, one_mul, mul_one] at ih ⊢
    simp only [add_assoc, add_left_comm, add_le_add_iff_left] at ih ⊢
    

Proof state:
a b : ℕ
ih :
  a * b + (a * b + (a * b + (a * b + (1 + (1 + (1 + 1)))))) ≤ a * a + (a * b + (b * a + (b * b + (1 + (1 + (1 + 1))))))
⊢ a * b + (a * b + (a * b + (a * b + (1 + (1 + (1 + 1)))))) ≤ a * a + (a * b + (b * a + (b * b + (1 + (1 + (1 + 1))))))

Next tactic:
exact ih
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  

Proof state:
n guess : ℕ
⊢ iter n guess * iter n guess ≤ n

Next tactic:
unfold sqrt.iter
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  

Proof state:
n guess : ℕ
⊢ ((let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) *
      let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) ≤
    n

Next tactic:
let next := (guess + n / guess) / 2
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  let next := (guess + n / guess) / 2
  

Proof state:
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
⊢ ((let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) *
      let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) ≤
    n

Next tactic:
by_cases h : next < guess
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  let next := (guess + n / guess) / 2
  by_cases h : next < guess
  

Proof state:
case pos
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
h : next < guess
⊢ ((let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) *
      let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) ≤
    n
case neg
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
h : ¬next < guess
⊢ ((let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) *
      let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) ≤
    n

Next tactic:
case pos => simpa only [dif_pos h] using sqrt.iter_sq_le n next
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  let next := (guess + n / guess) / 2
  by_cases h : next < guess
  

Proof state:
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
h : next < guess
⊢ ((let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) *
      let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) ≤
    n

Next tactic:
case pos => simpa only [dif_pos h] using sqrt.iter_sq_le n next
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  let next := (guess + n / guess) / 2
  by_cases h : next < guess
  case pos => 

Proof state:
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
h : next < guess
⊢ ((let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) *
      let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) ≤
    n

Next tactic:
simpa only [dif_pos h] using sqrt.iter_sq_le n next
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  let next := (guess + n / guess) / 2
  by_cases h : next < guess
  case pos => simpa only [dif_pos h] using sqrt.iter_sq_le n next
  

Proof state:
case neg
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
h : ¬next < guess
⊢ ((let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) *
      let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) ≤
    n

Next tactic:
case neg =>
    simp only [dif_neg h]
    apply Nat.mul_le_of_le_div
    apply le_of_add_le_add_left (a := guess)
    rw [← mul_two, ← le_div_iff_mul_le]
    · exact le_of_not_lt h
    · exact zero_lt_two
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  let next := (guess + n / guess) / 2
  by_cases h : next < guess
  case pos => simpa only [dif_pos h] using sqrt.iter_sq_le n next
  

Proof state:
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
h : ¬next < guess
⊢ ((let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) *
      let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) ≤
    n

Next tactic:
case neg =>
    simp only [dif_neg h]
    apply Nat.mul_le_of_le_div
    apply le_of_add_le_add_left (a := guess)
    rw [← mul_two, ← le_div_iff_mul_le]
    · exact le_of_not_lt h
    · exact zero_lt_two
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  let next := (guess + n / guess) / 2
  by_cases h : next < guess
  case pos => simpa only [dif_pos h] using sqrt.iter_sq_le n next
  case neg =>
    

Proof state:
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
h : ¬next < guess
⊢ ((let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) *
      let next := (guess + n / guess) / 2;
      if _h : next < guess then iter n next else guess) ≤
    n

Next tactic:
simp only [dif_neg h]
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  let next := (guess + n / guess) / 2
  by_cases h : next < guess
  case pos => simpa only [dif_pos h] using sqrt.iter_sq_le n next
  case neg =>
    simp only [dif_neg h]
    

Proof state:
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
h : ¬next < guess
⊢ guess * guess ≤ n

Next tactic:
apply Nat.mul_le_of_le_div
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  let next := (guess + n / guess) / 2
  by_cases h : next < guess
  case pos => simpa only [dif_pos h] using sqrt.iter_sq_le n next
  case neg =>
    simp only [dif_neg h]
    apply Nat.mul_le_of_le_div
    

Proof state:
case h
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
h : ¬next < guess
⊢ guess ≤ n / guess

Next tactic:
apply le_of_add_le_add_left (a := guess)
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  let next := (guess + n / guess) / 2
  by_cases h : next < guess
  case pos => simpa only [dif_pos h] using sqrt.iter_sq_le n next
  case neg =>
    simp only [dif_neg h]
    apply Nat.mul_le_of_le_div
    apply le_of_add_le_add_left (a := guess)
    

Proof state:
case h
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
h : ¬next < guess
⊢ guess + guess ≤ guess + n / guess

Next tactic:
rw [← mul_two, ← le_div_iff_mul_le]
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  let next := (guess + n / guess) / 2
  by_cases h : next < guess
  case pos => simpa only [dif_pos h] using sqrt.iter_sq_le n next
  case neg =>
    simp only [dif_neg h]
    apply Nat.mul_le_of_le_div
    apply le_of_add_le_add_left (a := guess)
    rw [← mul_two, ← le_div_iff_mul_le]
    · 

Proof state:
case h
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
h : ¬next < guess
⊢ guess ≤ (guess + n / guess) / 2

Next tactic:
exact le_of_not_lt h
lemma sqrt.iter_sq_le (n guess : ℕ) : sqrt.iter n guess * sqrt.iter n guess ≤ n := by
  unfold sqrt.iter
  let next := (guess + n / guess) / 2
  by_cases h : next < guess
  case pos => simpa only [dif_pos h] using sqrt.iter_sq_le n next
  case neg =>
    simp only [dif_neg h]
    apply Nat.mul_le_of_le_div
    apply le_of_add_le_add_left (a := guess)
    rw [← mul_two, ← le_div_iff_mul_le]
    · exact le_of_not_lt h
    · 

Proof state:
case h
n guess : ℕ
next : ℕ := (guess + n / guess) / 2
h : ¬next < guess
⊢ 0 < 2

Next tactic:
exact zero_lt_two
lemma sqrt.lt_iter_succ_sq (n guess : ℕ) (hn : n < (guess + 1) * (guess + 1)) :
    n < (sqrt.iter n guess + 1) * (sqrt.iter n guess + 1) := by
  

Proof state:
n guess : ℕ
hn : n < (guess + 1) * (guess + 1)
⊢ n < (iter n guess + 1) * (iter n guess + 1)

Next tactic:
unfold sqrt.iter
lemma sqrt.lt_iter_succ_sq (n guess : ℕ) (hn : n < (guess + 1) * (guess + 1)) :
    n < (sqrt.iter n guess + 1) * (sqrt.iter n guess + 1) := by
  unfold sqrt.iter
  -- m was `next`
  

Proof state:
n guess : ℕ
hn : n < (guess + 1) * (guess + 1)
⊢ n <
    ((let next := (guess + n / guess) / 2;
        if _h : next < guess then iter n next else guess) +
        1) *
      ((let next := (guess + n / guess) / 2;
        if _h : next < guess then iter n next else guess) +
        1)

Next tactic:
let m := (guess + n / guess) / 2
lemma sqrt.lt_iter_succ_sq (n guess : ℕ) (hn : n < (guess + 1) * (guess + 1)) :
    n < (sqrt.iter n guess + 1) * (sqrt.iter n guess + 1) := by
  unfold sqrt.iter
  -- m was `next`
  let m := (guess + n / guess) / 2
  

Proof state:
n guess : ℕ
hn : n < (guess + 1) * (guess + 1)
m : ℕ := (guess + n / guess) / 2
⊢ n <
    ((let next := (guess + n / guess) / 2;
        if _h : next < guess then iter n next else guess) +
        1) *
      ((let next := (guess + n / guess) / 2;
        if _h : next < guess then iter n next else guess) +
        1)

Next tactic:
by_cases h : m < guess