l3lab/ntp-mathlib huggingface dataset:
theorem le_mul_of_pos_right (h : 0 < n) : m ≤ m * n := by
  

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

Next tactic:
conv =>
    lhs
    rw [← mul_one m]
theorem le_mul_of_pos_right (h : 0 < n) : m ≤ m * n := by
  conv =>
    

Proof state:
m n k l : ℕ
h : 0 < n
| m ≤ m * n

Next tactic:
lhs
    rw [← mul_one m]
theorem le_mul_of_pos_right (h : 0 < n) : m ≤ m * n := by
  conv =>
    

Proof state:
m n k l : ℕ
h : 0 < n
| m ≤ m * n

Next tactic:
lhs
theorem le_mul_of_pos_right (h : 0 < n) : m ≤ m * n := by
  conv =>
    lhs
    

Proof state:
m n k l : ℕ
h : 0 < n
| m

Next tactic:
rw [← mul_one m]
theorem le_mul_of_pos_right (h : 0 < n) : m ≤ m * n := by
  conv =>
    lhs
    rw [← mul_one m]
  

Proof state:
m n k l : ℕ
h : 0 < n
⊢ m * 1 ≤ m * n

Next tactic:
exact mul_le_mul_of_nonneg_left h.nat_succ_le (zero_le _)
theorem le_add_pred_of_pos (n : ℕ) {i : ℕ} (hi : i ≠ 0) : n ≤ i + (n - 1) := by
  

Proof state:
m n✝ k l n i : ℕ
hi : i ≠ 0
⊢ n ≤ i + (n - 1)

Next tactic:
refine le_trans ?_ add_tsub_le_assoc
theorem le_add_pred_of_pos (n : ℕ) {i : ℕ} (hi : i ≠ 0) : n ≤ i + (n - 1) := by
  refine le_trans ?_ add_tsub_le_assoc
  

Proof state:
m n✝ k l n i : ℕ
hi : i ≠ 0
⊢ n ≤ i + n - 1

Next tactic:
simp [add_comm, Nat.add_sub_assoc, one_le_iff_ne_zero.2 hi]
theorem add_sub_one_le_mul (hm : m ≠ 0) (hn : n ≠ 0) : m + n - 1 ≤ m * n := by
  

Proof state:
m n k l : ℕ
hm : m ≠ 0
hn : n ≠ 0
⊢ m + n - 1 ≤ m * n

Next tactic:
cases m
theorem add_sub_one_le_mul (hm : m ≠ 0) (hn : n ≠ 0) : m + n - 1 ≤ m * n := by
  cases m
  · 

Proof state:
case zero
n k l : ℕ
hn : n ≠ 0
hm : zero ≠ 0
⊢ zero + n - 1 ≤ zero * n

Next tactic:
cases hm rfl
theorem add_sub_one_le_mul (hm : m ≠ 0) (hn : n ≠ 0) : m + n - 1 ≤ m * n := by
  cases m
  · cases hm rfl
  · 

Proof state:
case succ
n k l : ℕ
hn : n ≠ 0
n✝ : ℕ
hm : succ n✝ ≠ 0
⊢ succ n✝ + n - 1 ≤ succ n✝ * n

Next tactic:
rw [succ_add, Nat.add_one_sub_one, succ_mul]
theorem add_sub_one_le_mul (hm : m ≠ 0) (hn : n ≠ 0) : m + n - 1 ≤ m * n := by
  cases m
  · cases hm rfl
  · rw [succ_add, Nat.add_one_sub_one, succ_mul]
    

Proof state:
case succ
n k l : ℕ
hn : n ≠ 0
n✝ : ℕ
hm : succ n✝ ≠ 0
⊢ n✝ + n ≤ n✝ * n + n

Next tactic:
exact add_le_add_right (le_mul_of_one_le_right' $ succ_le_iff.2 $ pos_iff_ne_zero.2 hn) _
/-- 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
    

Proof state:
m n k l : ℕ
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 : ℕ
h : a + 1 < b + 1
⊢ P (a + 1) (b + 1)

Next tactic:
apply hd _ _ ((add_lt_add_iff_right _).1 h)
/-- 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)
    · 

Proof state:
case a
m n k l : ℕ
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 : ℕ
h : a + 1 < b + 1
⊢ P (a + 1) b

Next tactic:
have this : a + 1 = b ∨ a + 1 < b := by rwa [← le_iff_eq_or_lt, ← Nat.lt_succ_iff]
/-- 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 

Proof state:
m n k l : ℕ
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 : ℕ
h : a + 1 < b + 1
⊢ a + 1 = b ∨ a + 1 < b

Next tactic:
rwa [← le_iff_eq_or_lt, ← Nat.lt_succ_iff]
/-- 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]
      

Proof state:
case a
m n k l : ℕ
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 : ℕ
h : a + 1 < b + 1
this : a + 1 = b ∨ a + 1 < b
⊢ P (a + 1) b

Next tactic:
have wf : (a + 1) + b < (a + 1) + (b + 1) := by simp
/-- 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 

Proof state:
m n k l : ℕ
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 : ℕ
h : a + 1 < b + 1
this : a + 1 = b ∨ a + 1 < b
⊢ a + 1 + b < a + 1 + (b + 1)

Next tactic:
simp
/-- 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
      

Proof state:
case a
m n k l : ℕ
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 : ℕ
h : a + 1 < b + 1
this : a + 1 = b ∨ a + 1 < b
wf : a + 1 + b < a + 1 + (b + 1)
⊢ P (a + 1) b

Next tactic:
rcases this with (rfl | h)
/-- 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)
      · 

Proof state:
case a.inl
m n k l : ℕ
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 : ℕ
h : a + 1 < a + 1 + 1
wf : a + 1 + (a + 1) < a + 1 + (a + 1 + 1)
⊢ P (a + 1) (a + 1)

Next tactic:
exact ha _
/-- 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 _
      

Proof state:
case a.inr
m n k l : ℕ
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 : ℕ
h✝ : a + 1 < b + 1
wf : a + 1 + b < a + 1 + (b + 1)
h : a + 1 < b
⊢ P (a + 1) b

Next tactic:
apply diag_induction P ha hb hd (a + 1) b h
/-- 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
    

Proof state:
case a
m n k l : ℕ
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 : ℕ
h : a + 1 < b + 1
⊢ P a (b + 1)

Next tactic:
have _ : a + (b + 1) < (a + 1) + (b + 1) := by simp
/-- 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 

Proof state:
m n k l : ℕ
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 : ℕ
h : a + 1 < b + 1
⊢ a + (b + 1) < a + 1 + (b + 1)

Next tactic:
simp
/-- 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
    

Proof state:
case a
m n k l : ℕ
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 : ℕ
h : a + 1 < b + 1
x✝ : a + (b + 1) < a + 1 + (b + 1)
⊢ P a (b + 1)

Next tactic:
apply diag_induction P ha hb hd a (b + 1)
/-- 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)
    

Proof state:
case a
m n k l : ℕ
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 : ℕ
h : a + 1 < b + 1
x✝ : a + (b + 1) < a + 1 + (b + 1)
⊢ a < b + 1

Next tactic:
apply lt_of_le_of_lt (Nat.le_succ _) h
/-- 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
this : a + 1 = b ∨ a + 1 < b
wf : a + 1 + b < a + 1 + (b + 1)
h : a + 1 < b
⊢ (invImage (fun a => PSigma.casesOn a fun a snd => PSigma.casesOn snd fun b snd => a + b) instWellFoundedRelation).1
    { fst := a + 1, snd := { fst := b, snd := h } } { fst := succ a, snd := { fst := succ b, snd := h✝ } }

Next tactic:
{ assumption }
/-- 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
this : a + 1 = b ∨ a + 1 < b
wf : a + 1 + b < a + 1 + (b + 1)
h : a + 1 < b
⊢ (invImage (fun a => PSigma.casesOn a fun a snd => PSigma.casesOn snd fun b snd => a + b) instWellFoundedRelation).1
    { fst := a + 1, snd := { fst := b, snd := h } } { fst := succ a, snd := { fst := succ b, snd := h✝ } }

Next tactic:
assumption
/-- 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 }