l3lab/ntp-mathlib huggingface dataset:
/-- Given a predicate on two naturals `P : ℕ → ℕ → Prop`, `P a b` is true for all `a < b` if
`P (a + 1) (a + 1)` is true for all `a`, `P 0 (b + 1)` is true for all `b` and for all
`a < b`, `P (a + 1) b` is true and `P a (b + 1)` is true implies `P (a + 1) (b + 1)` is true. -/
@[elab_as_elim]
theorem diag_induction (P : ℕ → ℕ → Prop) (ha : ∀ a, P (a + 1) (a + 1)) (hb : ∀ b, P 0 (b + 1))
    (hd : ∀ a b, a < b → P (a + 1) b → P a (b + 1) → P (a + 1) (b + 1)) : ∀ a b, a < b → P a b
  | 0, b + 1, _ => hb _
  | a + 1, b + 1, h => by
    apply hd _ _ ((add_lt_add_iff_right _).1 h)
    · have this : a + 1 = b ∨ a + 1 < b := by rwa [← le_iff_eq_or_lt, ← Nat.lt_succ_iff]
      have wf : (a + 1) + b < (a + 1) + (b + 1) := by simp
      rcases this with (rfl | h)
      · exact ha _
      apply diag_induction P ha hb hd (a + 1) b h
    have _ : a + (b + 1) < (a + 1) + (b + 1) := by simp
    apply diag_induction P ha hb hd a (b + 1)
    apply lt_of_le_of_lt (Nat.le_succ _) h
  termination_by _ a b c => a + b
  decreasing_by { 

Proof state:
P : ℕ → ℕ → Prop
ha : ∀ (a : ℕ), P (a + 1) (a + 1)
hb : ∀ (b : ℕ), P 0 (b + 1)
hd : ∀ (a b : ℕ), a < b → P (a + 1) b → P a (b + 1) → P (a + 1) (b + 1)
_x✝ : (x : ℕ) ×' (x_1 : ℕ) ×' x < x_1
a✝² :
  ∀ (y : (x : ℕ) ×' (x_1 : ℕ) ×' x < x_1),
    (invImage (fun a => PSigma.casesOn a fun a snd => PSigma.casesOn snd fun b snd => a + b) instWellFoundedRelation).1
        y _x✝ →
      P y.1 y.2.1
x✝⁵ : ℕ
x✝⁴ : (x : ℕ) ×' x✝⁵ < x
a✝¹ :
  ∀ (y : (x : ℕ) ×' (x_1 : ℕ) ×' x < x_1),
    (invImage (fun a => PSigma.casesOn a fun a snd => PSigma.casesOn snd fun b snd => a + b) instWellFoundedRelation).1
        y { fst := x✝⁵, snd := x✝⁴ } →
      P y.1 y.2.1
x✝³ : ℕ
x✝² : x✝⁵ < x✝³
a✝ :
  ∀ (y : (x : ℕ) ×' (x_1 : ℕ) ×' x < x_1),
    (invImage (fun a => PSigma.casesOn a fun a snd => PSigma.casesOn snd fun b snd => a + b) instWellFoundedRelation).1
        y { fst := x✝⁵, snd := { fst := x✝³, snd := x✝² } } →
      P y.1 y.2.1
a b : ℕ
h : a + 1 < b + 1
x✝¹ :
  ∀ (y : (x : ℕ) ×' (x_1 : ℕ) ×' x < x_1),
    (invImage (fun a => PSigma.casesOn a fun a snd => PSigma.casesOn snd fun b snd => a + b) instWellFoundedRelation).1
        y { fst := succ a, snd := { fst := succ b, snd := h } } →
      P y.1 y.2.1
x✝ : a + (b + 1) < a + 1 + (b + 1)
⊢ (invImage (fun a => PSigma.casesOn a fun a snd => PSigma.casesOn snd fun b snd => a + b) instWellFoundedRelation).1
    { fst := a, snd := { fst := b + 1, snd := (_ : a < b + 1) } } { fst := succ a, snd := { fst := succ b, snd := h } }

Next tactic:
assumption
protected theorem div_le_of_le_mul' (h : m ≤ k * n) : m / k ≤ n :=
  (Nat.eq_zero_or_pos k).elim (fun k0 => by 

Proof state:
m n k l : ℕ
h : m ≤ k * n
k0 : k = 0
⊢ m / k ≤ n

Next tactic:
rw [k0, Nat.div_zero]
protected theorem div_le_of_le_mul' (h : m ≤ k * n) : m / k ≤ n :=
  (Nat.eq_zero_or_pos k).elim (fun k0 => by rw [k0, Nat.div_zero]; 

Proof state:
m n k l : ℕ
h : m ≤ k * n
k0 : k = 0
⊢ 0 ≤ n

Next tactic:
apply zero_le
protected theorem div_le_self' (m n : ℕ) : m / n ≤ m :=
  (Nat.eq_zero_or_pos n).elim (fun n0 => by 

Proof state:
m✝ n✝ k l m n : ℕ
n0 : n = 0
⊢ m / n ≤ m

Next tactic:
rw [n0, Nat.div_zero]
protected theorem div_le_self' (m n : ℕ) : m / n ≤ m :=
  (Nat.eq_zero_or_pos n).elim (fun n0 => by rw [n0, Nat.div_zero]; 

Proof state:
m✝ n✝ k l m n : ℕ
n0 : n = 0
⊢ 0 ≤ m

Next tactic:
apply zero_le
theorem eq_zero_of_le_div (hn : 2 ≤ n) (h : m ≤ m / n) : m = 0 :=
  eq_zero_of_mul_le hn <| by
    

Proof state:
m n k l : ℕ
hn : 2 ≤ n
h : m ≤ m / n
⊢ n * m ≤ m

Next tactic:
rw [mul_comm]
theorem eq_zero_of_le_div (hn : 2 ≤ n) (h : m ≤ m / n) : m = 0 :=
  eq_zero_of_mul_le hn <| by
    rw [mul_comm]; 

Proof state:
m n k l : ℕ
hn : 2 ≤ n
h : m ≤ m / n
⊢ m * n ≤ m

Next tactic:
exact (Nat.le_div_iff_mul_le' (lt_of_lt_of_le (by decide) hn)).1 h
theorem eq_zero_of_le_div (hn : 2 ≤ n) (h : m ≤ m / n) : m = 0 :=
  eq_zero_of_mul_le hn <| by
    rw [mul_comm]; exact (Nat.le_div_iff_mul_le' (lt_of_lt_of_le (by 

Proof state:
m n k l : ℕ
hn : 2 ≤ n
h : m ≤ m / n
⊢ 0 < 2

Next tactic:
decide
theorem div_mul_div_le_div (m n k : ℕ) : m / k * n / m ≤ n / k :=
  if hm0 : m = 0 then by 

Proof state:
m✝ n✝ k✝ l m n k : ℕ
hm0 : m = 0
⊢ m / k * n / m ≤ n / k

Next tactic:
simp [hm0]
theorem div_mul_div_le_div (m n k : ℕ) : m / k * n / m ≤ n / k :=
  if hm0 : m = 0 then by simp [hm0]
  else
    calc
      m / k * n / m ≤ n * m / k / m :=
        Nat.div_le_div_right (by 

Proof state:
m✝ n✝ k✝ l m n k : ℕ
hm0 : ¬m = 0
⊢ m / k * n ≤ n * m / k

Next tactic:
rw [mul_comm]
theorem div_mul_div_le_div (m n k : ℕ) : m / k * n / m ≤ n / k :=
  if hm0 : m = 0 then by simp [hm0]
  else
    calc
      m / k * n / m ≤ n * m / k / m :=
        Nat.div_le_div_right (by rw [mul_comm]; 

Proof state:
m✝ n✝ k✝ l m n k : ℕ
hm0 : ¬m = 0
⊢ n * (m / k) ≤ n * m / k

Next tactic:
exact mul_div_le_mul_div_assoc _ _ _
theorem div_mul_div_le_div (m n k : ℕ) : m / k * n / m ≤ n / k :=
  if hm0 : m = 0 then by simp [hm0]
  else
    calc
      m / k * n / m ≤ n * m / k / m :=
        Nat.div_le_div_right (by rw [mul_comm]; exact mul_div_le_mul_div_assoc _ _ _)
      _ = n / k := by
        

Proof state:
m✝ n✝ k✝ l m n k : ℕ
hm0 : ¬m = 0
⊢ n * m / k / m = n / k

Next tactic:
{ rw [Nat.div_div_eq_div_mul, mul_comm n, mul_comm k,
            Nat.mul_div_mul_left _ _ (Nat.pos_of_ne_zero hm0)] }
theorem div_mul_div_le_div (m n k : ℕ) : m / k * n / m ≤ n / k :=
  if hm0 : m = 0 then by simp [hm0]
  else
    calc
      m / k * n / m ≤ n * m / k / m :=
        Nat.div_le_div_right (by rw [mul_comm]; exact mul_div_le_mul_div_assoc _ _ _)
      _ = n / k := by
        { 

Proof state:
m✝ n✝ k✝ l m n k : ℕ
hm0 : ¬m = 0
⊢ n * m / k / m = n / k

Next tactic:
rw [Nat.div_div_eq_div_mul, mul_comm n, mul_comm k,
            Nat.mul_div_mul_left _ _ (Nat.pos_of_ne_zero hm0)]
theorem mul_div_mul_comm_of_dvd_dvd (hmk : k ∣ m) (hnl : l ∣ n) :
    m * n / (k * l) = m / k * (n / l) := by
  

Proof state:
m n k l : ℕ
hmk : k ∣ m
hnl : l ∣ n
⊢ m * n / (k * l) = m / k * (n / l)

Next tactic:
rcases k.eq_zero_or_pos with (rfl | hk0)
theorem mul_div_mul_comm_of_dvd_dvd (hmk : k ∣ m) (hnl : l ∣ n) :
    m * n / (k * l) = m / k * (n / l) := by
  rcases k.eq_zero_or_pos with (rfl | hk0); · 

Proof state:
case inl
m n l : ℕ
hnl : l ∣ n
hmk : 0 ∣ m
⊢ m * n / (0 * l) = m / 0 * (n / l)

Next tactic:
simp
theorem mul_div_mul_comm_of_dvd_dvd (hmk : k ∣ m) (hnl : l ∣ n) :
    m * n / (k * l) = m / k * (n / l) := by
  rcases k.eq_zero_or_pos with (rfl | hk0); · simp
  

Proof state:
case inr
m n k l : ℕ
hmk : k ∣ m
hnl : l ∣ n
hk0 : k > 0
⊢ m * n / (k * l) = m / k * (n / l)

Next tactic:
rcases l.eq_zero_or_pos with (rfl | hl0)
theorem mul_div_mul_comm_of_dvd_dvd (hmk : k ∣ m) (hnl : l ∣ n) :
    m * n / (k * l) = m / k * (n / l) := by
  rcases k.eq_zero_or_pos with (rfl | hk0); · simp
  rcases l.eq_zero_or_pos with (rfl | hl0); · 

Proof state:
case inr.inl
m n k : ℕ
hmk : k ∣ m
hk0 : k > 0
hnl : 0 ∣ n
⊢ m * n / (k * 0) = m / k * (n / 0)

Next tactic:
simp
theorem mul_div_mul_comm_of_dvd_dvd (hmk : k ∣ m) (hnl : l ∣ n) :
    m * n / (k * l) = m / k * (n / l) := by
  rcases k.eq_zero_or_pos with (rfl | hk0); · simp
  rcases l.eq_zero_or_pos with (rfl | hl0); · simp
  

Proof state:
case inr.inr
m n k l : ℕ
hmk : k ∣ m
hnl : l ∣ n
hk0 : k > 0
hl0 : l > 0
⊢ m * n / (k * l) = m / k * (n / l)

Next tactic:
obtain ⟨_, rfl⟩ := hmk
theorem mul_div_mul_comm_of_dvd_dvd (hmk : k ∣ m) (hnl : l ∣ n) :
    m * n / (k * l) = m / k * (n / l) := by
  rcases k.eq_zero_or_pos with (rfl | hk0); · simp
  rcases l.eq_zero_or_pos with (rfl | hl0); · simp
  obtain ⟨_, rfl⟩ := hmk
  

Proof state:
case inr.inr.intro
n k l : ℕ
hnl : l ∣ n
hk0 : k > 0
hl0 : l > 0
w✝ : ℕ
⊢ k * w✝ * n / (k * l) = k * w✝ / k * (n / l)

Next tactic:
obtain ⟨_, rfl⟩ := hnl
theorem mul_div_mul_comm_of_dvd_dvd (hmk : k ∣ m) (hnl : l ∣ n) :
    m * n / (k * l) = m / k * (n / l) := by
  rcases k.eq_zero_or_pos with (rfl | hk0); · simp
  rcases l.eq_zero_or_pos with (rfl | hl0); · simp
  obtain ⟨_, rfl⟩ := hmk
  obtain ⟨_, rfl⟩ := hnl
  

Proof state:
case inr.inr.intro.intro
k l : ℕ
hk0 : k > 0
hl0 : l > 0
w✝¹ w✝ : ℕ
⊢ k * w✝¹ * (l * w✝) / (k * l) = k * w✝¹ / k * (l * w✝ / l)

Next tactic:
rw [mul_mul_mul_comm, Nat.mul_div_cancel_left _ hk0, Nat.mul_div_cancel_left _ hl0,
    Nat.mul_div_cancel_left _ (mul_pos hk0 hl0)]
theorem le_half_of_half_lt_sub {a b : ℕ} (h : a / 2 < a - b) : b ≤ a / 2 := by
  

Proof state:
m n k l a b : ℕ
h : a / 2 < a - b
⊢ b ≤ a / 2

Next tactic:
rw [Nat.le_div_iff_mul_le two_pos]
theorem le_half_of_half_lt_sub {a b : ℕ} (h : a / 2 < a - b) : b ≤ a / 2 := by
  rw [Nat.le_div_iff_mul_le two_pos]
  

Proof state:
m n k l a b : ℕ
h : a / 2 < a - b
⊢ b * 2 ≤ a

Next tactic:
rw [Nat.div_lt_iff_lt_mul two_pos, Nat.mul_sub_right_distrib, lt_tsub_iff_right, mul_two a] at h
theorem le_half_of_half_lt_sub {a b : ℕ} (h : a / 2 < a - b) : b ≤ a / 2 := by
  rw [Nat.le_div_iff_mul_le two_pos]
  rw [Nat.div_lt_iff_lt_mul two_pos, Nat.mul_sub_right_distrib, lt_tsub_iff_right, mul_two a] at h
  

Proof state:
m n k l a b : ℕ
h : a + b * 2 < a + a
⊢ b * 2 ≤ a

Next tactic:
exact le_of_lt (Nat.lt_of_add_lt_add_left h)
theorem half_le_of_sub_le_half {a b : ℕ} (h : a - b ≤ a / 2) : a / 2 ≤ b := by
  

Proof state:
m n k l a b : ℕ
h : a - b ≤ a / 2
⊢ a / 2 ≤ b

Next tactic:
rw [Nat.le_div_iff_mul_le two_pos, Nat.mul_sub_right_distrib, tsub_le_iff_right, mul_two,
    add_le_add_iff_left] at h
theorem half_le_of_sub_le_half {a b : ℕ} (h : a - b ≤ a / 2) : a / 2 ≤ b := by
  rw [Nat.le_div_iff_mul_le two_pos, Nat.mul_sub_right_distrib, tsub_le_iff_right, mul_two,
    add_le_add_iff_left] at h
  

Proof state:
m n k l a b : ℕ
h : a ≤ b * 2
⊢ a / 2 ≤ b

Next tactic:
rw [← Nat.mul_div_left b two_pos]
theorem half_le_of_sub_le_half {a b : ℕ} (h : a - b ≤ a / 2) : a / 2 ≤ b := by
  rw [Nat.le_div_iff_mul_le two_pos, Nat.mul_sub_right_distrib, tsub_le_iff_right, mul_two,
    add_le_add_iff_left] at h
  rw [← Nat.mul_div_left b two_pos]
  

Proof state:
m n k l a b : ℕ
h : a ≤ b * 2
⊢ a / 2 ≤ b * 2 / 2

Next tactic:
exact Nat.div_le_div_right h
theorem two_mul_odd_div_two (hn : n % 2 = 1) : 2 * (n / 2) = n - 1 := by
  

Proof state:
m n k l : ℕ
hn : n % 2 = 1
⊢ 2 * (n / 2) = n - 1

Next tactic:
conv =>
    rhs
    rw [← Nat.mod_add_div n 2, hn, @add_tsub_cancel_left]
theorem two_mul_odd_div_two (hn : n % 2 = 1) : 2 * (n / 2) = n - 1 := by
  conv =>
    

Proof state:
m n k l : ℕ
hn : n % 2 = 1
| 2 * (n / 2) = n - 1

Next tactic:
rhs
    rw [← Nat.mod_add_div n 2, hn, @add_tsub_cancel_left]
theorem two_mul_odd_div_two (hn : n % 2 = 1) : 2 * (n / 2) = n - 1 := by
  conv =>
    

Proof state:
m n k l : ℕ
hn : n % 2 = 1
| 2 * (n / 2) = n - 1

Next tactic:
rhs
theorem two_mul_odd_div_two (hn : n % 2 = 1) : 2 * (n / 2) = n - 1 := by
  conv =>
    rhs
    

Proof state:
m n k l : ℕ
hn : n % 2 = 1
| n - 1

Next tactic:
rw [← Nat.mod_add_div n 2, hn, @add_tsub_cancel_left]
protected theorem div_div_self (h : n ∣ m) (hm : m ≠ 0) : m / (m / n) = n := by
  

Proof state:
m n k l : ℕ
h : n ∣ m
hm : m ≠ 0
⊢ m / (m / n) = n

Next tactic:
rcases h with ⟨_, rfl⟩
protected theorem div_div_self (h : n ∣ m) (hm : m ≠ 0) : m / (m / n) = n := by
  rcases h with ⟨_, rfl⟩
  

Proof state:
case intro
n k l w✝ : ℕ
hm : n * w✝ ≠ 0
⊢ n * w✝ / (n * w✝ / n) = n

Next tactic:
rw [mul_ne_zero_iff] at hm
protected theorem div_div_self (h : n ∣ m) (hm : m ≠ 0) : m / (m / n) = n := by
  rcases h with ⟨_, rfl⟩
  rw [mul_ne_zero_iff] at hm
  

Proof state:
case intro
n k l w✝ : ℕ
hm : n ≠ 0 ∧ w✝ ≠ 0
⊢ n * w✝ / (n * w✝ / n) = n

Next tactic:
rw [mul_div_right _ (Nat.pos_of_ne_zero hm.1), mul_div_left _ (Nat.pos_of_ne_zero hm.2)]
theorem mod_mul_right_div_self (m n k : ℕ) : m % (n * k) / n = m / n % k := by
  

Proof state:
m✝ n✝ k✝ l m n k : ℕ
⊢ m % (n * k) / n = m / n % k

Next tactic:
rcases Nat.eq_zero_or_pos n with (rfl | hn)
theorem mod_mul_right_div_self (m n k : ℕ) : m % (n * k) / n = m / n % k := by
  rcases Nat.eq_zero_or_pos n with (rfl | hn); 

Proof state:
case inl
m✝ n k✝ l m k : ℕ
⊢ m % (0 * k) / 0 = m / 0 % k
case inr m✝ n✝ k✝ l m n k : ℕ hn : n > 0 ⊢ m % (n * k) / n = m / n % k

Next tactic:
simp [mod_zero]
theorem mod_mul_right_div_self (m n k : ℕ) : m % (n * k) / n = m / n % k := by
  rcases Nat.eq_zero_or_pos n with (rfl | hn); simp [mod_zero]
  

Proof state:
case inr
m✝ n✝ k✝ l m n k : ℕ
hn : n > 0
⊢ m % (n * k) / n = m / n % k

Next tactic:
rcases Nat.eq_zero_or_pos k with (rfl | hk)
theorem mod_mul_right_div_self (m n k : ℕ) : m % (n * k) / n = m / n % k := by
  rcases Nat.eq_zero_or_pos n with (rfl | hn); simp [mod_zero]
  rcases Nat.eq_zero_or_pos k with (rfl | hk); 

Proof state:
case inr.inl
m✝ n✝ k l m n : ℕ
hn : n > 0
⊢ m % (n * 0) / n = m / n % 0
case inr.inr m✝ n✝ k✝ l m n k : ℕ hn : n > 0 hk : k > 0 ⊢ m % (n * k) / n = m / n % k

Next tactic:
simp [mod_zero]
theorem mod_mul_right_div_self (m n k : ℕ) : m % (n * k) / n = m / n % k := by
  rcases Nat.eq_zero_or_pos n with (rfl | hn); simp [mod_zero]
  rcases Nat.eq_zero_or_pos k with (rfl | hk); simp [mod_zero]
  

Proof state:
case inr.inr
m✝ n✝ k✝ l m n k : ℕ
hn : n > 0
hk : k > 0
⊢ m % (n * k) / n = m / n % k

Next tactic:
conv_rhs => rw [← mod_add_div m (n * k)]
theorem mod_mul_right_div_self (m n k : ℕ) : m % (n * k) / n = m / n % k := by
  rcases Nat.eq_zero_or_pos n with (rfl | hn); simp [mod_zero]
  rcases Nat.eq_zero_or_pos k with (rfl | hk); simp [mod_zero]
  conv_rhs => 

Proof state:
m✝ n✝ k✝ l m n k : ℕ
hn : n > 0
hk : k > 0
| m / n % k

Next tactic:
rw [← mod_add_div m (n * k)]
theorem mod_mul_right_div_self (m n k : ℕ) : m % (n * k) / n = m / n % k := by
  rcases Nat.eq_zero_or_pos n with (rfl | hn); simp [mod_zero]
  rcases Nat.eq_zero_or_pos k with (rfl | hk); simp [mod_zero]
  conv_rhs => rw [← mod_add_div m (n * k)]
  

Proof state:
case inr.inr
m✝ n✝ k✝ l m n k : ℕ
hn : n > 0
hk : k > 0
⊢ m % (n * k) / n = (m % (n * k) + n * k * (m / (n * k))) / n % k

Next tactic:
rw [mul_assoc, add_mul_div_left _ _ hn, add_mul_mod_self_left,
    mod_eq_of_lt (Nat.div_lt_of_lt_mul (mod_lt _ (mul_pos hn hk)))]
theorem mod_mul_left_div_self (m n k : ℕ) : m % (k * n) / n = m / n % k := by
  

Proof state:
m✝ n✝ k✝ l m n k : ℕ
⊢ m % (k * n) / n = m / n % k

Next tactic:
rw [mul_comm k, mod_mul_right_div_self]
theorem not_dvd_of_pos_of_lt (h1 : 0 < n) (h2 : n < m) : ¬m ∣ n := by
  

Proof state:
m n k l : ℕ
h1 : 0 < n
h2 : n < m
⊢ ¬m ∣ n

Next tactic:
rintro ⟨k, rfl⟩
theorem not_dvd_of_pos_of_lt (h1 : 0 < n) (h2 : n < m) : ¬m ∣ n := by
  rintro ⟨k, rfl⟩
  

Proof state:
case intro
m k✝ l k : ℕ
h1 : 0 < m * k
h2 : m * k < m
⊢ False

Next tactic:
rcases Nat.eq_zero_or_pos k with (rfl | hk)
theorem not_dvd_of_pos_of_lt (h1 : 0 < n) (h2 : n < m) : ¬m ∣ n := by
  rintro ⟨k, rfl⟩
  rcases Nat.eq_zero_or_pos k with (rfl | hk)
  · 

Proof state:
case intro.inl
m k l : ℕ
h1 : 0 < m * 0
h2 : m * 0 < m
⊢ False

Next tactic:
exact lt_irrefl 0 h1
theorem not_dvd_of_pos_of_lt (h1 : 0 < n) (h2 : n < m) : ¬m ∣ n := by
  rintro ⟨k, rfl⟩
  rcases Nat.eq_zero_or_pos k with (rfl | hk)
  · exact lt_irrefl 0 h1
  · 

Proof state:
case intro.inr
m k✝ l k : ℕ
h1 : 0 < m * k
h2 : m * k < m
hk : k > 0
⊢ False

Next tactic:
exact not_lt.2 (le_mul_of_pos_right hk) h2
/-- If `m` and `n` are equal mod `k`, `m - n` is zero mod `k`. -/
theorem sub_mod_eq_zero_of_mod_eq (h : m % k = n % k) : (m - n) % k = 0 := by
  

Proof state:
m n k l : ℕ
h : m % k = n % k
⊢ (m - n) % k = 0

Next tactic:
rw [← Nat.mod_add_div m k, ← Nat.mod_add_div n k, ← h, tsub_add_eq_tsub_tsub,
    @add_tsub_cancel_left, ← mul_tsub k, Nat.mul_mod_right]
theorem one_mod_of_ne_one : ∀ {n : ℕ}, n ≠ 1 → 1 % n = 1
  | 0, _ | (n + 2), _ => by 

Proof state:
m n k l : ℕ
x✝ : 0 ≠ 1
⊢ 1 % 0 = 1

Next tactic:
simp
theorem one_mod_of_ne_one : ∀ {n : ℕ}, n ≠ 1 → 1 % n = 1
  | 0, _ | (n + 2), _ => by 

Proof state:
m n✝ k l n : ℕ
x✝ : n + 2 ≠ 1
⊢ 1 % (n + 2) = 1

Next tactic:
simp
theorem add_mod_eq_ite :
    (m + n) % k = if k ≤ m % k + n % k then m % k + n % k - k else m % k + n % k := by
  

Proof state:
m n k l : ℕ
⊢ (m + n) % k = if k ≤ m % k + n % k then m % k + n % k - k else m % k + n % k

Next tactic:
cases k
theorem add_mod_eq_ite :
    (m + n) % k = if k ≤ m % k + n % k then m % k + n % k - k else m % k + n % k := by
  cases k; 

Proof state:
case zero
m n l : ℕ
⊢ (m + n) % zero = if zero ≤ m % zero + n % zero then m % zero + n % zero - zero else m % zero + n % zero
case succ
m n l n✝ : ℕ
⊢ (m + n) % succ n✝ =
    if succ n✝ ≤ m % succ n✝ + n % succ n✝ then m % succ n✝ + n % succ n✝ - succ n✝ else m % succ n✝ + n % succ n✝

Next tactic:
simp [mod_zero]
theorem add_mod_eq_ite :
    (m + n) % k = if k ≤ m % k + n % k then m % k + n % k - k else m % k + n % k := by
  cases k; simp [mod_zero]
  

Proof state:
case succ
m n l n✝ : ℕ
⊢ (m + n) % succ n✝ =
    if succ n✝ ≤ m % succ n✝ + n % succ n✝ then m % succ n✝ + n % succ n✝ - succ n✝ else m % succ n✝ + n % succ n✝

Next tactic:
rw [Nat.add_mod]
theorem add_mod_eq_ite :
    (m + n) % k = if k ≤ m % k + n % k then m % k + n % k - k else m % k + n % k := by
  cases k; simp [mod_zero]
  rw [Nat.add_mod]
  

Proof state:
case succ
m n l n✝ : ℕ
⊢ (m % succ n✝ + n % succ n✝) % succ n✝ =
    if succ n✝ ≤ m % succ n✝ + n % succ n✝ then m % succ n✝ + n % succ n✝ - succ n✝ else m % succ n✝ + n % succ n✝

Next tactic:
split_ifs with h
theorem add_mod_eq_ite :
    (m + n) % k = if k ≤ m % k + n % k then m % k + n % k - k else m % k + n % k := by
  cases k; simp [mod_zero]
  rw [Nat.add_mod]
  split_ifs with h
  · 

Proof state:
case pos
m n l n✝ : ℕ
h : succ n✝ ≤ m % succ n✝ + n % succ n✝
⊢ (m % succ n✝ + n % succ n✝) % succ n✝ = m % succ n✝ + n % succ n✝ - succ n✝

Next tactic:
rw [Nat.mod_eq_sub_mod h, Nat.mod_eq_of_lt]
theorem add_mod_eq_ite :
    (m + n) % k = if k ≤ m % k + n % k then m % k + n % k - k else m % k + n % k := by
  cases k; simp [mod_zero]
  rw [Nat.add_mod]
  split_ifs with h
  · rw [Nat.mod_eq_sub_mod h, Nat.mod_eq_of_lt]
    

Proof state:
case pos
m n l n✝ : ℕ
h : succ n✝ ≤ m % succ n✝ + n % succ n✝
⊢ m % succ n✝ + n % succ n✝ - succ n✝ < succ n✝

Next tactic:
exact
      (tsub_lt_iff_right h).mpr (Nat.add_lt_add (m.mod_lt (zero_lt_succ _))
        (n.mod_lt (zero_lt_succ _)))
theorem add_mod_eq_ite :
    (m + n) % k = if k ≤ m % k + n % k then m % k + n % k - k else m % k + n % k := by
  cases k; simp [mod_zero]
  rw [Nat.add_mod]
  split_ifs with h
  · rw [Nat.mod_eq_sub_mod h, Nat.mod_eq_of_lt]
    exact
      (tsub_lt_iff_right h).mpr (Nat.add_lt_add (m.mod_lt (zero_lt_succ _))
        (n.mod_lt (zero_lt_succ _)))
  · 

Proof state:
case neg
m n l n✝ : ℕ
h : ¬succ n✝ ≤ m % succ n✝ + n % succ n✝
⊢ (m % succ n✝ + n % succ n✝) % succ n✝ = m % succ n✝ + n % succ n✝

Next tactic:
exact Nat.mod_eq_of_lt (lt_of_not_ge h)
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  

Proof state:
m n k l : ℕ
⊢ m / n = m ↔ m = 0 ∨ n = 1

Next tactic:
constructor
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · 

Proof state:
case mp
m n k l : ℕ
⊢ m / n = m → m = 0 ∨ n = 1

Next tactic:
intro
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    

Proof state:
case mp
m n k l : ℕ
a✝ : m / n = m
⊢ m = 0 ∨ n = 1

Next tactic:
match n with
    | 0 => simp_all
    | 1 =>
      right
      rfl
    | n+2 =>
      left
      have : m / (n + 2) ≤ m / 2 := div_le_div_left (by simp) (by decide)
      refine eq_zero_of_le_half ?_
      simp_all
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    match n with
    | 0 => 

Proof state:
m n k l : ℕ
a✝ : m / 0 = m
⊢ m = 0 ∨ 0 = 1

Next tactic:
simp_all
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    match n with
    | 0 => simp_all
    | 1 =>
      

Proof state:
m n k l : ℕ
a✝ : m / 1 = m
⊢ m = 0 ∨ 1 = 1

Next tactic:
right
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    match n with
    | 0 => simp_all
    | 1 =>
      right
      

Proof state:
case h
m n k l : ℕ
a✝ : m / 1 = m
⊢ 1 = 1

Next tactic:
rfl
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    match n with
    | 0 => simp_all
    | 1 =>
      right
      rfl
    | n+2 =>
      

Proof state:
m n✝ k l n : ℕ
a✝ : m / (n + 2) = m
⊢ m = 0 ∨ n + 2 = 1

Next tactic:
left
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    match n with
    | 0 => simp_all
    | 1 =>
      right
      rfl
    | n+2 =>
      left
      

Proof state:
case h
m n✝ k l n : ℕ
a✝ : m / (n + 2) = m
⊢ m = 0

Next tactic:
have : m / (n + 2) ≤ m / 2 := div_le_div_left (by simp) (by decide)
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    match n with
    | 0 => simp_all
    | 1 =>
      right
      rfl
    | n+2 =>
      left
      have : m / (n + 2) ≤ m / 2 := div_le_div_left (by 

Proof state:
m n✝ k l n : ℕ
a✝ : m / (n + 2) = m
⊢ 2 ≤ n + 2

Next tactic:
simp
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    match n with
    | 0 => simp_all
    | 1 =>
      right
      rfl
    | n+2 =>
      left
      have : m / (n + 2) ≤ m / 2 := div_le_div_left (by simp) (by 

Proof state:
m n✝ k l n : ℕ
a✝ : m / (n + 2) = m
⊢ 0 < 2

Next tactic:
decide
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    match n with
    | 0 => simp_all
    | 1 =>
      right
      rfl
    | n+2 =>
      left
      have : m / (n + 2) ≤ m / 2 := div_le_div_left (by simp) (by decide)
      

Proof state:
case h
m n✝ k l n : ℕ
a✝ : m / (n + 2) = m
this : m / (n + 2) ≤ m / 2
⊢ m = 0

Next tactic:
refine eq_zero_of_le_half ?_
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    match n with
    | 0 => simp_all
    | 1 =>
      right
      rfl
    | n+2 =>
      left
      have : m / (n + 2) ≤ m / 2 := div_le_div_left (by simp) (by decide)
      refine eq_zero_of_le_half ?_
      

Proof state:
case h
m n✝ k l n : ℕ
a✝ : m / (n + 2) = m
this : m / (n + 2) ≤ m / 2
⊢ m ≤ m / 2

Next tactic:
simp_all
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    match n with
    | 0 => simp_all
    | 1 =>
      right
      rfl
    | n+2 =>
      left
      have : m / (n + 2) ≤ m / 2 := div_le_div_left (by simp) (by decide)
      refine eq_zero_of_le_half ?_
      simp_all
  · 

Proof state:
case mpr
m n k l : ℕ
⊢ m = 0 ∨ n = 1 → m / n = m

Next tactic:
rintro (rfl | rfl)
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    match n with
    | 0 => simp_all
    | 1 =>
      right
      rfl
    | n+2 =>
      left
      have : m / (n + 2) ≤ m / 2 := div_le_div_left (by simp) (by decide)
      refine eq_zero_of_le_half ?_
      simp_all
  · rintro (rfl | rfl) <;> 

Proof state:
case mpr.inl
n k l : ℕ
⊢ 0 / n = 0

Next tactic:
simp
theorem div_eq_self : m / n = m ↔ m = 0 ∨ n = 1 := by
  constructor
  · intro
    match n with
    | 0 => simp_all
    | 1 =>
      right
      rfl
    | n+2 =>
      left
      have : m / (n + 2) ≤ m / 2 := div_le_div_left (by simp) (by decide)
      refine eq_zero_of_le_half ?_
      simp_all
  · rintro (rfl | rfl) <;> 

Proof state:
case mpr.inr
m k l : ℕ
⊢ m / 1 = m

Next tactic:
simp
theorem div_eq_sub_mod_div : m / n = (m - m % n) / n := by
  

Proof state:
m n k l : ℕ
⊢ m / n = (m - m % n) / n

Next tactic:
by_cases n0 : n = 0
theorem div_eq_sub_mod_div : m / n = (m - m % n) / n := by
  by_cases n0 : n = 0
  · 

Proof state:
case pos
m n k l : ℕ
n0 : n = 0
⊢ m / n = (m - m % n) / n

Next tactic:
rw [n0, Nat.div_zero, Nat.div_zero]
theorem div_eq_sub_mod_div : m / n = (m - m % n) / n := by
  by_cases n0 : n = 0
  · rw [n0, Nat.div_zero, Nat.div_zero]
  · 

Proof state:
case neg
m n k l : ℕ
n0 : ¬n = 0
⊢ m / n = (m - m % n) / n

Next tactic:
have : m - m % n = n * (m / n) := by
      rw [tsub_eq_iff_eq_add_of_le (Nat.mod_le _ _), add_comm, mod_add_div]
theorem div_eq_sub_mod_div : m / n = (m - m % n) / n := by
  by_cases n0 : n = 0
  · rw [n0, Nat.div_zero, Nat.div_zero]
  · have : m - m % n = n * (m / n) := by
      

Proof state:
m n k l : ℕ
n0 : ¬n = 0
⊢ m - m % n = n * (m / n)

Next tactic:
rw [tsub_eq_iff_eq_add_of_le (Nat.mod_le _ _), add_comm, mod_add_div]