l3lab/ntp-mathlib huggingface dataset:
theorem toFinsupp_append {R : Type*} [AddZeroClass R] (l₁ l₂ : List R)
    [DecidablePred (getD (l₁ ++ l₂) · 0 ≠ 0)] [DecidablePred (getD l₁ · 0 ≠ 0)]
    [DecidablePred (getD l₂ · 0 ≠ 0)] :
    toFinsupp (l₁ ++ l₂) =
      toFinsupp l₁ + (toFinsupp l₂).embDomain (addLeftEmbedding l₁.length) := by
  ext n
  simp only [toFinsupp_apply, Finsupp.add_apply]
  cases lt_or_le n l₁.length with
  | inl h =>
    rw [getD_append _ _ _ _ h, Finsupp.embDomain_notin_range, add_zero]
    rintro ⟨k, rfl : length l₁ + k = n⟩
    exact h.not_le (self_le_add_right _ _)
  | inr h =>
    

Proof state:
case h.inr
M : Type u_1
inst✝⁵ : Zero M
l : List M
inst✝⁴ : DecidablePred fun x => getD l x 0 ≠ 0
n✝ : ℕ
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => getD (l₁ ++ l₂) x 0 ≠ 0
inst✝¹ : DecidablePred fun x => getD l₁ x 0 ≠ 0
inst✝ : DecidablePred fun x => getD l₂ x 0 ≠ 0
n : ℕ
h : length l₁ ≤ n
⊢ getD (l₁ ++ l₂) n 0 = getD l₁ n 0 + (Finsupp.embDomain (addLeftEmbedding (length l₁)) (toFinsupp l₂)) n

Next tactic:
rcases exists_add_of_le h with ⟨k, rfl⟩
theorem toFinsupp_append {R : Type*} [AddZeroClass R] (l₁ l₂ : List R)
    [DecidablePred (getD (l₁ ++ l₂) · 0 ≠ 0)] [DecidablePred (getD l₁ · 0 ≠ 0)]
    [DecidablePred (getD l₂ · 0 ≠ 0)] :
    toFinsupp (l₁ ++ l₂) =
      toFinsupp l₁ + (toFinsupp l₂).embDomain (addLeftEmbedding l₁.length) := by
  ext n
  simp only [toFinsupp_apply, Finsupp.add_apply]
  cases lt_or_le n l₁.length with
  | inl h =>
    rw [getD_append _ _ _ _ h, Finsupp.embDomain_notin_range, add_zero]
    rintro ⟨k, rfl : length l₁ + k = n⟩
    exact h.not_le (self_le_add_right _ _)
  | inr h =>
    rcases exists_add_of_le h with ⟨k, rfl⟩
    

Proof state:
case h.inr.intro
M : Type u_1
inst✝⁵ : Zero M
l : List M
inst✝⁴ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => getD (l₁ ++ l₂) x 0 ≠ 0
inst✝¹ : DecidablePred fun x => getD l₁ x 0 ≠ 0
inst✝ : DecidablePred fun x => getD l₂ x 0 ≠ 0
k : ℕ
h : length l₁ ≤ length l₁ + k
⊢ getD (l₁ ++ l₂) (length l₁ + k) 0 =
    getD l₁ (length l₁ + k) 0 + (Finsupp.embDomain (addLeftEmbedding (length l₁)) (toFinsupp l₂)) (length l₁ + k)

Next tactic:
rw [getD_append_right _ _ _ _ h, add_tsub_cancel_left, getD_eq_default _ _ h, zero_add]
theorem toFinsupp_append {R : Type*} [AddZeroClass R] (l₁ l₂ : List R)
    [DecidablePred (getD (l₁ ++ l₂) · 0 ≠ 0)] [DecidablePred (getD l₁ · 0 ≠ 0)]
    [DecidablePred (getD l₂ · 0 ≠ 0)] :
    toFinsupp (l₁ ++ l₂) =
      toFinsupp l₁ + (toFinsupp l₂).embDomain (addLeftEmbedding l₁.length) := by
  ext n
  simp only [toFinsupp_apply, Finsupp.add_apply]
  cases lt_or_le n l₁.length with
  | inl h =>
    rw [getD_append _ _ _ _ h, Finsupp.embDomain_notin_range, add_zero]
    rintro ⟨k, rfl : length l₁ + k = n⟩
    exact h.not_le (self_le_add_right _ _)
  | inr h =>
    rcases exists_add_of_le h with ⟨k, rfl⟩
    rw [getD_append_right _ _ _ _ h, add_tsub_cancel_left, getD_eq_default _ _ h, zero_add]
    

Proof state:
case h.inr.intro
M : Type u_1
inst✝⁵ : Zero M
l : List M
inst✝⁴ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝³ : AddZeroClass R
l₁ l₂ : List R
inst✝² : DecidablePred fun x => getD (l₁ ++ l₂) x 0 ≠ 0
inst✝¹ : DecidablePred fun x => getD l₁ x 0 ≠ 0
inst✝ : DecidablePred fun x => getD l₂ x 0 ≠ 0
k : ℕ
h : length l₁ ≤ length l₁ + k
⊢ getD l₂ k 0 = (Finsupp.embDomain (addLeftEmbedding (length l₁)) (toFinsupp l₂)) (length l₁ + k)

Next tactic:
exact Eq.symm (Finsupp.embDomain_apply _ _ _)
theorem toFinsupp_cons_eq_single_add_embDomain {R : Type*} [AddZeroClass R] (x : R) (xs : List R)
    [DecidablePred (getD (x::xs) · 0 ≠ 0)] [DecidablePred (getD xs · 0 ≠ 0)] :
    toFinsupp (x::xs) =
      Finsupp.single 0 x + (toFinsupp xs).embDomain ⟨Nat.succ, Nat.succ_injective⟩ := by
  

Proof state:
M : Type u_1
inst✝⁴ : Zero M
l : List M
inst✝³ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝² : AddZeroClass R
x : R
xs : List R
inst✝¹ : DecidablePred fun x_1 => getD (x :: xs) x_1 0 ≠ 0
inst✝ : DecidablePred fun x => getD xs x 0 ≠ 0
⊢ toFinsupp (x :: xs) =
    (fun₀ | 0 => x) + Finsupp.embDomain { toFun := Nat.succ, inj' := Nat.succ_injective } (toFinsupp xs)

Next tactic:
classical
    convert toFinsupp_append [x] xs using 3
    · exact (toFinsupp_singleton x).symm
    · ext n
      exact add_comm n 1
theorem toFinsupp_cons_eq_single_add_embDomain {R : Type*} [AddZeroClass R] (x : R) (xs : List R)
    [DecidablePred (getD (x::xs) · 0 ≠ 0)] [DecidablePred (getD xs · 0 ≠ 0)] :
    toFinsupp (x::xs) =
      Finsupp.single 0 x + (toFinsupp xs).embDomain ⟨Nat.succ, Nat.succ_injective⟩ := by
  classical
    

Proof state:
M : Type u_1
inst✝⁴ : Zero M
l : List M
inst✝³ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝² : AddZeroClass R
x : R
xs : List R
inst✝¹ : DecidablePred fun x_1 => getD (x :: xs) x_1 0 ≠ 0
inst✝ : DecidablePred fun x => getD xs x 0 ≠ 0
⊢ toFinsupp (x :: xs) =
    (fun₀ | 0 => x) + Finsupp.embDomain { toFun := Nat.succ, inj' := Nat.succ_injective } (toFinsupp xs)

Next tactic:
convert toFinsupp_append [x] xs using 3
theorem toFinsupp_cons_eq_single_add_embDomain {R : Type*} [AddZeroClass R] (x : R) (xs : List R)
    [DecidablePred (getD (x::xs) · 0 ≠ 0)] [DecidablePred (getD xs · 0 ≠ 0)] :
    toFinsupp (x::xs) =
      Finsupp.single 0 x + (toFinsupp xs).embDomain ⟨Nat.succ, Nat.succ_injective⟩ := by
  classical
    convert toFinsupp_append [x] xs using 3
    · 

Proof state:
case h.e'_3.h.e'_5
M : Type u_1
inst✝⁴ : Zero M
l : List M
inst✝³ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝² : AddZeroClass R
x : R
xs : List R
inst✝¹ : DecidablePred fun x_1 => getD (x :: xs) x_1 0 ≠ 0
inst✝ : DecidablePred fun x => getD xs x 0 ≠ 0
⊢ (fun₀ | 0 => x) = toFinsupp [x]

Next tactic:
exact (toFinsupp_singleton x).symm
theorem toFinsupp_cons_eq_single_add_embDomain {R : Type*} [AddZeroClass R] (x : R) (xs : List R)
    [DecidablePred (getD (x::xs) · 0 ≠ 0)] [DecidablePred (getD xs · 0 ≠ 0)] :
    toFinsupp (x::xs) =
      Finsupp.single 0 x + (toFinsupp xs).embDomain ⟨Nat.succ, Nat.succ_injective⟩ := by
  classical
    convert toFinsupp_append [x] xs using 3
    · exact (toFinsupp_singleton x).symm
    · 

Proof state:
case h.e'_3.h.e'_6.h.e'_5
M : Type u_1
inst✝⁴ : Zero M
l : List M
inst✝³ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝² : AddZeroClass R
x : R
xs : List R
inst✝¹ : DecidablePred fun x_1 => getD (x :: xs) x_1 0 ≠ 0
inst✝ : DecidablePred fun x => getD xs x 0 ≠ 0
⊢ { toFun := Nat.succ, inj' := Nat.succ_injective } = addLeftEmbedding (length [x])

Next tactic:
ext n
theorem toFinsupp_cons_eq_single_add_embDomain {R : Type*} [AddZeroClass R] (x : R) (xs : List R)
    [DecidablePred (getD (x::xs) · 0 ≠ 0)] [DecidablePred (getD xs · 0 ≠ 0)] :
    toFinsupp (x::xs) =
      Finsupp.single 0 x + (toFinsupp xs).embDomain ⟨Nat.succ, Nat.succ_injective⟩ := by
  classical
    convert toFinsupp_append [x] xs using 3
    · exact (toFinsupp_singleton x).symm
    · ext n
      

Proof state:
case h.e'_3.h.e'_6.h.e'_5.h
M : Type u_1
inst✝⁴ : Zero M
l : List M
inst✝³ : DecidablePred fun x => getD l x 0 ≠ 0
n✝ : ℕ
R : Type u_2
inst✝² : AddZeroClass R
x : R
xs : List R
inst✝¹ : DecidablePred fun x_1 => getD (x :: xs) x_1 0 ≠ 0
inst✝ : DecidablePred fun x => getD xs x 0 ≠ 0
n : ℕ
⊢ { toFun := Nat.succ, inj' := Nat.succ_injective } n = (addLeftEmbedding (length [x])) n

Next tactic:
exact add_comm n 1
theorem toFinsupp_concat_eq_toFinsupp_add_single {R : Type*} [AddZeroClass R] (x : R) (xs : List R)
    [DecidablePred fun i => getD (xs ++ [x]) i 0 ≠ 0] [DecidablePred fun i => getD xs i 0 ≠ 0] :
    toFinsupp (xs ++ [x]) = toFinsupp xs + Finsupp.single xs.length x := by
  

Proof state:
M : Type u_1
inst✝⁴ : Zero M
l : List M
inst✝³ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝² : AddZeroClass R
x : R
xs : List R
inst✝¹ : DecidablePred fun i => getD (xs ++ [x]) i 0 ≠ 0
inst✝ : DecidablePred fun i => getD xs i 0 ≠ 0
⊢ toFinsupp (xs ++ [x]) = toFinsupp xs + fun₀ | length xs => x

Next tactic:
classical rw [toFinsupp_append, toFinsupp_singleton, Finsupp.embDomain_single,
    addLeftEmbedding_apply, add_zero]
theorem toFinsupp_concat_eq_toFinsupp_add_single {R : Type*} [AddZeroClass R] (x : R) (xs : List R)
    [DecidablePred fun i => getD (xs ++ [x]) i 0 ≠ 0] [DecidablePred fun i => getD xs i 0 ≠ 0] :
    toFinsupp (xs ++ [x]) = toFinsupp xs + Finsupp.single xs.length x := by
  classical 

Proof state:
M : Type u_1
inst✝⁴ : Zero M
l : List M
inst✝³ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝² : AddZeroClass R
x : R
xs : List R
inst✝¹ : DecidablePred fun i => getD (xs ++ [x]) i 0 ≠ 0
inst✝ : DecidablePred fun i => getD xs i 0 ≠ 0
⊢ toFinsupp (xs ++ [x]) = toFinsupp xs + fun₀ | length xs => x

Next tactic:
rw [toFinsupp_append, toFinsupp_singleton, Finsupp.embDomain_single,
    addLeftEmbedding_apply, add_zero]
theorem toFinsupp_eq_sum_map_enum_single {R : Type*} [AddMonoid R] (l : List R)
    [DecidablePred (getD l · 0 ≠ 0)] :
    toFinsupp l = (l.enum.map fun nr : ℕ × R => Finsupp.single nr.1 nr.2).sum := by
  /- porting note: todo: `induction` fails to substitute `l = []` in
  `[DecidablePred (getD l · 0 ≠ 0)]`, so we manually do some `revert`/`intro` as a workaround -/
  

Proof state:
M : Type u_1
inst✝³ : Zero M
l✝ : List M
inst✝² : DecidablePred fun x => getD l✝ x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝¹ : AddMonoid R
l : List R
inst✝ : DecidablePred fun x => getD l x 0 ≠ 0
⊢ toFinsupp l = sum (map (fun nr => fun₀ | nr.1 => nr.2) (enum l))

Next tactic:
revert l
theorem toFinsupp_eq_sum_map_enum_single {R : Type*} [AddMonoid R] (l : List R)
    [DecidablePred (getD l · 0 ≠ 0)] :
    toFinsupp l = (l.enum.map fun nr : ℕ × R => Finsupp.single nr.1 nr.2).sum := by
  /- porting note: todo: `induction` fails to substitute `l = []` in
  `[DecidablePred (getD l · 0 ≠ 0)]`, so we manually do some `revert`/`intro` as a workaround -/
  revert l; 

Proof state:
M : Type u_1
inst✝² : Zero M
l : List M
inst✝¹ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝ : AddMonoid R
⊢ ∀ (l : List R) [inst : DecidablePred fun x => getD l x 0 ≠ 0],
    toFinsupp l = sum (map (fun nr => fun₀ | nr.1 => nr.2) (enum l))

Next tactic:
intro l
theorem toFinsupp_eq_sum_map_enum_single {R : Type*} [AddMonoid R] (l : List R)
    [DecidablePred (getD l · 0 ≠ 0)] :
    toFinsupp l = (l.enum.map fun nr : ℕ × R => Finsupp.single nr.1 nr.2).sum := by
  /- porting note: todo: `induction` fails to substitute `l = []` in
  `[DecidablePred (getD l · 0 ≠ 0)]`, so we manually do some `revert`/`intro` as a workaround -/
  revert l; intro l
  

Proof state:
M : Type u_1
inst✝² : Zero M
l✝ : List M
inst✝¹ : DecidablePred fun x => getD l✝ x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝ : AddMonoid R
l : List R
⊢ ∀ [inst : DecidablePred fun x => getD l x 0 ≠ 0], toFinsupp l = sum (map (fun nr => fun₀ | nr.1 => nr.2) (enum l))

Next tactic:
induction l using List.reverseRecOn with
  | H0 => exact toFinsupp_nil
  | H1 x xs ih =>
    classical simp [toFinsupp_concat_eq_toFinsupp_add_single, enum_append, ih]
theorem toFinsupp_eq_sum_map_enum_single {R : Type*} [AddMonoid R] (l : List R)
    [DecidablePred (getD l · 0 ≠ 0)] :
    toFinsupp l = (l.enum.map fun nr : ℕ × R => Finsupp.single nr.1 nr.2).sum := by
  /- porting note: todo: `induction` fails to substitute `l = []` in
  `[DecidablePred (getD l · 0 ≠ 0)]`, so we manually do some `revert`/`intro` as a workaround -/
  revert l; intro l
  induction l using List.reverseRecOn with
  

Proof state:
case H0
M : Type u_1
inst✝² : Zero M
l : List M
inst✝¹ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝ : AddMonoid R
⊢ ∀ [inst : DecidablePred fun x => getD [] x 0 ≠ 0], toFinsupp [] = sum (map (fun nr => fun₀ | nr.1 => nr.2) (enum []))

Next tactic:
| H0 => exact toFinsupp_nil
theorem toFinsupp_eq_sum_map_enum_single {R : Type*} [AddMonoid R] (l : List R)
    [DecidablePred (getD l · 0 ≠ 0)] :
    toFinsupp l = (l.enum.map fun nr : ℕ × R => Finsupp.single nr.1 nr.2).sum := by
  /- porting note: todo: `induction` fails to substitute `l = []` in
  `[DecidablePred (getD l · 0 ≠ 0)]`, so we manually do some `revert`/`intro` as a workaround -/
  revert l; intro l
  induction l using List.reverseRecOn with
  | H0 => 

Proof state:
case H0
M : Type u_1
inst✝² : Zero M
l : List M
inst✝¹ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝ : AddMonoid R
⊢ ∀ [inst : DecidablePred fun x => getD [] x 0 ≠ 0], toFinsupp [] = sum (map (fun nr => fun₀ | nr.1 => nr.2) (enum []))

Next tactic:
exact toFinsupp_nil
theorem toFinsupp_eq_sum_map_enum_single {R : Type*} [AddMonoid R] (l : List R)
    [DecidablePred (getD l · 0 ≠ 0)] :
    toFinsupp l = (l.enum.map fun nr : ℕ × R => Finsupp.single nr.1 nr.2).sum := by
  /- porting note: todo: `induction` fails to substitute `l = []` in
  `[DecidablePred (getD l · 0 ≠ 0)]`, so we manually do some `revert`/`intro` as a workaround -/
  revert l; intro l
  induction l using List.reverseRecOn with
  | H0 => exact toFinsupp_nil
  

Proof state:
case H1
M : Type u_1
inst✝² : Zero M
l : List M
inst✝¹ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝ : AddMonoid R
x : List R
xs : R
ih :
  ∀ [inst : DecidablePred fun x_1 => getD x x_1 0 ≠ 0], toFinsupp x = sum (map (fun nr => fun₀ | nr.1 => nr.2) (enum x))
⊢ ∀ [inst : DecidablePred fun x_1 => getD (x ++ [xs]) x_1 0 ≠ 0],
    toFinsupp (x ++ [xs]) = sum (map (fun nr => fun₀ | nr.1 => nr.2) (enum (x ++ [xs])))

Next tactic:
| H1 x xs ih =>
    classical simp [toFinsupp_concat_eq_toFinsupp_add_single, enum_append, ih]
theorem toFinsupp_eq_sum_map_enum_single {R : Type*} [AddMonoid R] (l : List R)
    [DecidablePred (getD l · 0 ≠ 0)] :
    toFinsupp l = (l.enum.map fun nr : ℕ × R => Finsupp.single nr.1 nr.2).sum := by
  /- porting note: todo: `induction` fails to substitute `l = []` in
  `[DecidablePred (getD l · 0 ≠ 0)]`, so we manually do some `revert`/`intro` as a workaround -/
  revert l; intro l
  induction l using List.reverseRecOn with
  | H0 => exact toFinsupp_nil
  | H1 x xs ih =>
    

Proof state:
case H1
M : Type u_1
inst✝² : Zero M
l : List M
inst✝¹ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝ : AddMonoid R
x : List R
xs : R
ih :
  ∀ [inst : DecidablePred fun x_1 => getD x x_1 0 ≠ 0], toFinsupp x = sum (map (fun nr => fun₀ | nr.1 => nr.2) (enum x))
⊢ ∀ [inst : DecidablePred fun x_1 => getD (x ++ [xs]) x_1 0 ≠ 0],
    toFinsupp (x ++ [xs]) = sum (map (fun nr => fun₀ | nr.1 => nr.2) (enum (x ++ [xs])))

Next tactic:
classical simp [toFinsupp_concat_eq_toFinsupp_add_single, enum_append, ih]
theorem toFinsupp_eq_sum_map_enum_single {R : Type*} [AddMonoid R] (l : List R)
    [DecidablePred (getD l · 0 ≠ 0)] :
    toFinsupp l = (l.enum.map fun nr : ℕ × R => Finsupp.single nr.1 nr.2).sum := by
  /- porting note: todo: `induction` fails to substitute `l = []` in
  `[DecidablePred (getD l · 0 ≠ 0)]`, so we manually do some `revert`/`intro` as a workaround -/
  revert l; intro l
  induction l using List.reverseRecOn with
  | H0 => exact toFinsupp_nil
  | H1 x xs ih =>
    classical 

Proof state:
case H1
M : Type u_1
inst✝² : Zero M
l : List M
inst✝¹ : DecidablePred fun x => getD l x 0 ≠ 0
n : ℕ
R : Type u_2
inst✝ : AddMonoid R
x : List R
xs : R
ih :
  ∀ [inst : DecidablePred fun x_1 => getD x x_1 0 ≠ 0], toFinsupp x = sum (map (fun nr => fun₀ | nr.1 => nr.2) (enum x))
⊢ ∀ [inst : DecidablePred fun x_1 => getD (x ++ [xs]) x_1 0 ≠ 0],
    toFinsupp (x ++ [xs]) = sum (map (fun nr => fun₀ | nr.1 => nr.2) (enum (x ++ [xs])))

Next tactic:
simp [toFinsupp_concat_eq_toFinsupp_add_single, enum_append, ih]
@[simp]
theorem hyperoperation_zero (m : ℕ) : hyperoperation 0 m = Nat.succ :=
  funext fun k => by 

Proof state:
m k : ℕ
⊢ hyperoperation 0 m k = Nat.succ k

Next tactic:
rw [hyperoperation, Nat.succ_eq_add_one]
theorem hyperoperation_ge_three_eq_one (n m : ℕ) : hyperoperation (n + 3) m 0 = 1 := by
  

Proof state:
n m : ℕ
⊢ hyperoperation (n + 3) m 0 = 1

Next tactic:
rw [hyperoperation]
theorem hyperoperation_recursion (n m k : ℕ) :
    hyperoperation (n + 1) m (k + 1) = hyperoperation n m (hyperoperation (n + 1) m k) := by
  

Proof state:
n m k : ℕ
⊢ hyperoperation (n + 1) m (k + 1) = hyperoperation n m (hyperoperation (n + 1) m k)

Next tactic:
rw [hyperoperation]
@[simp]
theorem hyperoperation_one : hyperoperation 1 = (· + ·) := by
  

Proof state:
⊢ hyperoperation 1 = fun x x_1 => x + x_1

Next tactic:
ext m k
@[simp]
theorem hyperoperation_one : hyperoperation 1 = (· + ·) := by
  ext m k
  

Proof state:
case h.h
m k : ℕ
⊢ hyperoperation 1 m k = m + k

Next tactic:
induction' k with bn bih
@[simp]
theorem hyperoperation_one : hyperoperation 1 = (· + ·) := by
  ext m k
  induction' k with bn bih
  · 

Proof state:
case h.h.zero
m : ℕ
⊢ hyperoperation 1 m Nat.zero = m + Nat.zero

Next tactic:
rw [Nat.add_zero m, hyperoperation]
@[simp]
theorem hyperoperation_one : hyperoperation 1 = (· + ·) := by
  ext m k
  induction' k with bn bih
  · rw [Nat.add_zero m, hyperoperation]
  · 

Proof state:
case h.h.succ
m bn : ℕ
bih : hyperoperation 1 m bn = m + bn
⊢ hyperoperation 1 m (Nat.succ bn) = m + Nat.succ bn

Next tactic:
rw [hyperoperation_recursion, bih, hyperoperation_zero]
@[simp]
theorem hyperoperation_one : hyperoperation 1 = (· + ·) := by
  ext m k
  induction' k with bn bih
  · rw [Nat.add_zero m, hyperoperation]
  · rw [hyperoperation_recursion, bih, hyperoperation_zero]
    

Proof state:
case h.h.succ
m bn : ℕ
bih : hyperoperation 1 m bn = m + bn
⊢ Nat.succ (m + bn) = m + Nat.succ bn

Next tactic:
exact Nat.add_assoc m bn 1
@[simp]
theorem hyperoperation_two : hyperoperation 2 = (· * ·) := by
  

Proof state:
⊢ hyperoperation 2 = fun x x_1 => x * x_1

Next tactic:
ext m k
@[simp]
theorem hyperoperation_two : hyperoperation 2 = (· * ·) := by
  ext m k
  

Proof state:
case h.h
m k : ℕ
⊢ hyperoperation 2 m k = m * k

Next tactic:
induction' k with bn bih
@[simp]
theorem hyperoperation_two : hyperoperation 2 = (· * ·) := by
  ext m k
  induction' k with bn bih
  · 

Proof state:
case h.h.zero
m : ℕ
⊢ hyperoperation 2 m Nat.zero = m * Nat.zero

Next tactic:
rw [hyperoperation]
@[simp]
theorem hyperoperation_two : hyperoperation 2 = (· * ·) := by
  ext m k
  induction' k with bn bih
  · rw [hyperoperation]
    

Proof state:
case h.h.zero
m : ℕ
⊢ 0 = m * Nat.zero

Next tactic:
exact (Nat.mul_zero m).symm
@[simp]
theorem hyperoperation_two : hyperoperation 2 = (· * ·) := by
  ext m k
  induction' k with bn bih
  · rw [hyperoperation]
    exact (Nat.mul_zero m).symm
  · 

Proof state:
case h.h.succ
m bn : ℕ
bih : hyperoperation 2 m bn = m * bn
⊢ hyperoperation 2 m (Nat.succ bn) = m * Nat.succ bn

Next tactic:
rw [hyperoperation_recursion, hyperoperation_one, bih]
@[simp]
theorem hyperoperation_two : hyperoperation 2 = (· * ·) := by
  ext m k
  induction' k with bn bih
  · rw [hyperoperation]
    exact (Nat.mul_zero m).symm
  · rw [hyperoperation_recursion, hyperoperation_one, bih]
    -- porting note: was `ring`
    

Proof state:
case h.h.succ
m bn : ℕ
bih : hyperoperation 2 m bn = m * bn
⊢ (fun x x_1 => x + x_1) m (m * bn) = m * Nat.succ bn

Next tactic:
dsimp only
@[simp]
theorem hyperoperation_two : hyperoperation 2 = (· * ·) := by
  ext m k
  induction' k with bn bih
  · rw [hyperoperation]
    exact (Nat.mul_zero m).symm
  · rw [hyperoperation_recursion, hyperoperation_one, bih]
    -- porting note: was `ring`
    dsimp only
    

Proof state:
case h.h.succ
m bn : ℕ
bih : hyperoperation 2 m bn = m * bn
⊢ m + m * bn = m * Nat.succ bn

Next tactic:
nth_rewrite 1 [← mul_one m]
@[simp]
theorem hyperoperation_two : hyperoperation 2 = (· * ·) := by
  ext m k
  induction' k with bn bih
  · rw [hyperoperation]
    exact (Nat.mul_zero m).symm
  · rw [hyperoperation_recursion, hyperoperation_one, bih]
    -- porting note: was `ring`
    dsimp only
    nth_rewrite 1 [← mul_one m]
    

Proof state:
case h.h.succ
m bn : ℕ
bih : hyperoperation 2 m bn = m * bn
⊢ m * 1 + m * bn = m * Nat.succ bn

Next tactic:
rw [← mul_add, add_comm, Nat.succ_eq_add_one]
@[simp]
theorem hyperoperation_three : hyperoperation 3 = (· ^ ·) := by
  

Proof state:
⊢ hyperoperation 3 = fun x x_1 => x ^ x_1

Next tactic:
ext m k
@[simp]
theorem hyperoperation_three : hyperoperation 3 = (· ^ ·) := by
  ext m k
  

Proof state:
case h.h
m k : ℕ
⊢ hyperoperation 3 m k = m ^ k

Next tactic:
induction' k with bn bih
@[simp]
theorem hyperoperation_three : hyperoperation 3 = (· ^ ·) := by
  ext m k
  induction' k with bn bih
  · 

Proof state:
case h.h.zero
m : ℕ
⊢ hyperoperation 3 m Nat.zero = m ^ Nat.zero

Next tactic:
rw [hyperoperation_ge_three_eq_one]
@[simp]
theorem hyperoperation_three : hyperoperation 3 = (· ^ ·) := by
  ext m k
  induction' k with bn bih
  · rw [hyperoperation_ge_three_eq_one]
    

Proof state:
case h.h.zero
m : ℕ
⊢ 1 = m ^ Nat.zero

Next tactic:
exact (pow_zero m).symm
@[simp]
theorem hyperoperation_three : hyperoperation 3 = (· ^ ·) := by
  ext m k
  induction' k with bn bih
  · rw [hyperoperation_ge_three_eq_one]
    exact (pow_zero m).symm
  · 

Proof state:
case h.h.succ
m bn : ℕ
bih : hyperoperation 3 m bn = m ^ bn
⊢ hyperoperation 3 m (Nat.succ bn) = m ^ Nat.succ bn

Next tactic:
rw [hyperoperation_recursion, hyperoperation_two, bih]
@[simp]
theorem hyperoperation_three : hyperoperation 3 = (· ^ ·) := by
  ext m k
  induction' k with bn bih
  · rw [hyperoperation_ge_three_eq_one]
    exact (pow_zero m).symm
  · rw [hyperoperation_recursion, hyperoperation_two, bih]
    

Proof state:
case h.h.succ
m bn : ℕ
bih : hyperoperation 3 m bn = m ^ bn
⊢ (fun x x_1 => x * x_1) m (m ^ bn) = m ^ Nat.succ bn

Next tactic:
exact (pow_succ m bn).symm
theorem hyperoperation_ge_two_eq_self (n m : ℕ) : hyperoperation (n + 2) m 1 = m := by
  

Proof state:
n m : ℕ
⊢ hyperoperation (n + 2) m 1 = m

Next tactic:
induction' n with nn nih
theorem hyperoperation_ge_two_eq_self (n m : ℕ) : hyperoperation (n + 2) m 1 = m := by
  induction' n with nn nih
  · 

Proof state:
case zero
m : ℕ
⊢ hyperoperation (Nat.zero + 2) m 1 = m

Next tactic:
rw [hyperoperation_two]
theorem hyperoperation_ge_two_eq_self (n m : ℕ) : hyperoperation (n + 2) m 1 = m := by
  induction' n with nn nih
  · rw [hyperoperation_two]
    

Proof state:
case zero
m : ℕ
⊢ (fun x x_1 => x * x_1) m 1 = m

Next tactic:
ring
theorem hyperoperation_ge_two_eq_self (n m : ℕ) : hyperoperation (n + 2) m 1 = m := by
  induction' n with nn nih
  · rw [hyperoperation_two]
    ring
  · 

Proof state:
case succ
m nn : ℕ
nih : hyperoperation (nn + 2) m 1 = m
⊢ hyperoperation (Nat.succ nn + 2) m 1 = m

Next tactic:
rw [hyperoperation_recursion, hyperoperation_ge_three_eq_one, nih]
theorem hyperoperation_two_two_eq_four (n : ℕ) : hyperoperation (n + 1) 2 2 = 4 := by
  

Proof state:
n : ℕ
⊢ hyperoperation (n + 1) 2 2 = 4

Next tactic:
induction' n with nn nih
theorem hyperoperation_two_two_eq_four (n : ℕ) : hyperoperation (n + 1) 2 2 = 4 := by
  induction' n with nn nih
  · 

Proof state:
case zero
⊢ hyperoperation (Nat.zero + 1) 2 2 = 4

Next tactic:
rw [hyperoperation_one]
theorem hyperoperation_two_two_eq_four (n : ℕ) : hyperoperation (n + 1) 2 2 = 4 := by
  induction' n with nn nih
  · rw [hyperoperation_one]
  · 

Proof state:
case succ
nn : ℕ
nih : hyperoperation (nn + 1) 2 2 = 4
⊢ hyperoperation (Nat.succ nn + 1) 2 2 = 4

Next tactic:
rw [hyperoperation_recursion, hyperoperation_ge_two_eq_self, nih]
theorem hyperoperation_ge_three_one (n : ℕ) : ∀ k : ℕ, hyperoperation (n + 3) 1 k = 1 := by
  

Proof state:
n : ℕ
⊢ ∀ (k : ℕ), hyperoperation (n + 3) 1 k = 1

Next tactic:
induction' n with nn nih
theorem hyperoperation_ge_three_one (n : ℕ) : ∀ k : ℕ, hyperoperation (n + 3) 1 k = 1 := by
  induction' n with nn nih
  · 

Proof state:
case zero
⊢ ∀ (k : ℕ), hyperoperation (Nat.zero + 3) 1 k = 1

Next tactic:
intro k
theorem hyperoperation_ge_three_one (n : ℕ) : ∀ k : ℕ, hyperoperation (n + 3) 1 k = 1 := by
  induction' n with nn nih
  · intro k
    

Proof state:
case zero
k : ℕ
⊢ hyperoperation (Nat.zero + 3) 1 k = 1

Next tactic:
rw [hyperoperation_three]
theorem hyperoperation_ge_three_one (n : ℕ) : ∀ k : ℕ, hyperoperation (n + 3) 1 k = 1 := by
  induction' n with nn nih
  · intro k
    rw [hyperoperation_three]
    

Proof state:
case zero
k : ℕ
⊢ (fun x x_1 => x ^ x_1) 1 k = 1

Next tactic:
dsimp