l3lab/ntp-mathlib huggingface dataset:
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · 

Proof state:
case right
f : ℕ → ℕ
⊢ ∃ m, ∀ (n : ℕ), (fun n => (unpair n).2) n < ack m n

Next tactic:
refine' ⟨0, fun n => _⟩
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    

Proof state:
case right
f : ℕ → ℕ
n : ℕ
⊢ (fun n => (unpair n).2) n < ack 0 n

Next tactic:
rw [ack_zero, lt_succ_iff]
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    

Proof state:
case right
f : ℕ → ℕ
n : ℕ
⊢ (fun n => (unpair n).2) n ≤ n

Next tactic:
exact unpair_right_le n
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  

Proof state:
case pair
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
IHf : ∃ m, ∀ (n : ℕ), f n < ack m n
IHg : ∃ m, ∀ (n : ℕ), g n < ack m n
⊢ ∃ m, ∀ (n : ℕ), (fun n => pair (f n) (g n)) n < ack m n
case comp
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
IHf : ∃ m, ∀ (n : ℕ), f n < ack m n
IHg : ∃ m, ∀ (n : ℕ), g n < ack m n
⊢ ∃ m, ∀ (n : ℕ), (fun n => f (g n)) n < ack m n
case prec
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
IHf : ∃ m, ∀ (n : ℕ), f n < ack m n
IHg : ∃ m, ∀ (n : ℕ), g n < ack m n
⊢ ∃ m, ∀ (n : ℕ), unpaired (fun z n => rec (f z) (fun y IH => g (pair z (pair y IH))) n) n < ack m n

Next tactic:
all_goals cases' IHf with a ha; cases' IHg with b hb
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals 

Proof state:
case pair
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
IHf : ∃ m, ∀ (n : ℕ), f n < ack m n
IHg : ∃ m, ∀ (n : ℕ), g n < ack m n
⊢ ∃ m, ∀ (n : ℕ), (fun n => pair (f n) (g n)) n < ack m n

Next tactic:
cases' IHf with a ha
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals cases' IHf with a ha; 

Proof state:
case pair.intro
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
IHg : ∃ m, ∀ (n : ℕ), g n < ack m n
a : ℕ
ha : ∀ (n : ℕ), f n < ack a n
⊢ ∃ m, ∀ (n : ℕ), (fun n => pair (f n) (g n)) n < ack m n

Next tactic:
cases' IHg with b hb
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals 

Proof state:
case comp
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
IHf : ∃ m, ∀ (n : ℕ), f n < ack m n
IHg : ∃ m, ∀ (n : ℕ), g n < ack m n
⊢ ∃ m, ∀ (n : ℕ), (fun n => f (g n)) n < ack m n

Next tactic:
cases' IHf with a ha
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals cases' IHf with a ha; 

Proof state:
case comp.intro
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
IHg : ∃ m, ∀ (n : ℕ), g n < ack m n
a : ℕ
ha : ∀ (n : ℕ), f n < ack a n
⊢ ∃ m, ∀ (n : ℕ), (fun n => f (g n)) n < ack m n

Next tactic:
cases' IHg with b hb
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals 

Proof state:
case prec
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
IHf : ∃ m, ∀ (n : ℕ), f n < ack m n
IHg : ∃ m, ∀ (n : ℕ), g n < ack m n
⊢ ∃ m, ∀ (n : ℕ), unpaired (fun z n => rec (f z) (fun y IH => g (pair z (pair y IH))) n) n < ack m n

Next tactic:
cases' IHf with a ha
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals cases' IHf with a ha; 

Proof state:
case prec.intro
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
IHg : ∃ m, ∀ (n : ℕ), g n < ack m n
a : ℕ
ha : ∀ (n : ℕ), f n < ack a n
⊢ ∃ m, ∀ (n : ℕ), unpaired (fun z n => rec (f z) (fun y IH => g (pair z (pair y IH))) n) n < ack m n

Next tactic:
cases' IHg with b hb
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals cases' IHf with a ha; cases' IHg with b hb
  -- Pairing:
  · 

Proof state:
case pair.intro.intro
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
a : ℕ
ha : ∀ (n : ℕ), f n < ack a n
b : ℕ
hb : ∀ (n : ℕ), g n < ack b n
⊢ ∃ m, ∀ (n : ℕ), (fun n => pair (f n) (g n)) n < ack m n

Next tactic:
refine'
      ⟨max a b + 3, fun n =>
        (pair_lt_max_add_one_sq _ _).trans_le <|
          (Nat.pow_le_pow_left (add_le_add_right _ _) 2).trans <|
            ack_add_one_sq_lt_ack_add_three _ _⟩
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals cases' IHf with a ha; cases' IHg with b hb
  -- Pairing:
  · refine'
      ⟨max a b + 3, fun n =>
        (pair_lt_max_add_one_sq _ _).trans_le <|
          (Nat.pow_le_pow_left (add_le_add_right _ _) 2).trans <|
            ack_add_one_sq_lt_ack_add_three _ _⟩
    

Proof state:
case pair.intro.intro
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
a : ℕ
ha : ∀ (n : ℕ), f n < ack a n
b : ℕ
hb : ∀ (n : ℕ), g n < ack b n
n : ℕ
⊢ max (f n) (g n) ≤ ack (max a b) n

Next tactic:
rw [max_ack_left]
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals cases' IHf with a ha; cases' IHg with b hb
  -- Pairing:
  · refine'
      ⟨max a b + 3, fun n =>
        (pair_lt_max_add_one_sq _ _).trans_le <|
          (Nat.pow_le_pow_left (add_le_add_right _ _) 2).trans <|
            ack_add_one_sq_lt_ack_add_three _ _⟩
    rw [max_ack_left]
    

Proof state:
case pair.intro.intro
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
a : ℕ
ha : ∀ (n : ℕ), f n < ack a n
b : ℕ
hb : ∀ (n : ℕ), g n < ack b n
n : ℕ
⊢ max (f n) (g n) ≤ max (ack a n) (ack b n)

Next tactic:
exact max_le_max (ha n).le (hb n).le
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals cases' IHf with a ha; cases' IHg with b hb
  -- Pairing:
  · refine'
      ⟨max a b + 3, fun n =>
        (pair_lt_max_add_one_sq _ _).trans_le <|
          (Nat.pow_le_pow_left (add_le_add_right _ _) 2).trans <|
            ack_add_one_sq_lt_ack_add_three _ _⟩
    rw [max_ack_left]
    exact max_le_max (ha n).le (hb n).le
  -- Composition:
  · 

Proof state:
case comp.intro.intro
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
a : ℕ
ha : ∀ (n : ℕ), f n < ack a n
b : ℕ
hb : ∀ (n : ℕ), g n < ack b n
⊢ ∃ m, ∀ (n : ℕ), (fun n => f (g n)) n < ack m n

Next tactic:
exact
      ⟨max a b + 2, fun n =>
        (ha _).trans <| (ack_strictMono_right a <| hb n).trans <| ack_ack_lt_ack_max_add_two a b n⟩
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals cases' IHf with a ha; cases' IHg with b hb
  -- Pairing:
  · refine'
      ⟨max a b + 3, fun n =>
        (pair_lt_max_add_one_sq _ _).trans_le <|
          (Nat.pow_le_pow_left (add_le_add_right _ _) 2).trans <|
            ack_add_one_sq_lt_ack_add_three _ _⟩
    rw [max_ack_left]
    exact max_le_max (ha n).le (hb n).le
  -- Composition:
  · exact
      ⟨max a b + 2, fun n =>
        (ha _).trans <| (ack_strictMono_right a <| hb n).trans <| ack_ack_lt_ack_max_add_two a b n⟩
  -- Primitive recursion operator:
  · -- We prove this simpler inequality first.
    

Proof state:
case prec.intro.intro
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
a : ℕ
ha : ∀ (n : ℕ), f n < ack a n
b : ℕ
hb : ∀ (n : ℕ), g n < ack b n
⊢ ∃ m, ∀ (n : ℕ), unpaired (fun z n => rec (f z) (fun y IH => g (pair z (pair y IH))) n) n < ack m n

Next tactic:
have :
      ∀ {m n},
        rec (f m) (fun y IH => g <| pair m <| pair y IH) n < ack (max a b + 9) (m + n) := by
      intro m n
      -- We induct on n.
      induction' n with n IH
      -- The base case is easy.
      · apply (ha m).trans (ack_strictMono_left m <| (le_max_left a b).trans_lt _)
        linarith
      · -- We get rid of the first `pair`.
        simp only [ge_iff_le]
        apply (hb _).trans ((ack_pair_lt _ _ _).trans_le _)
        -- If m is the maximum, we get a very weak inequality.
        cases' lt_or_le _ m with h₁ h₁
        · rw [max_eq_left h₁.le]
          exact ack_le_ack (Nat.add_le_add (le_max_right a b) <| by norm_num)
                           (self_le_add_right m _)
        rw [max_eq_right h₁]
        -- We get rid of the second `pair`.
        apply (ack_pair_lt _ _ _).le.trans
        -- If n is the maximum, we get a very weak inequality.
        cases' lt_or_le _ n with h₂ h₂
        · rw [max_eq_left h₂.le, add_assoc]
          exact
            ack_le_ack (Nat.add_le_add (le_max_right a b) <| by norm_num)
              ((le_succ n).trans <| self_le_add_left _ _)
        rw [max_eq_right h₂]
        -- We now use the inductive hypothesis, and some simple algebraic manipulation.
        apply (ack_strictMono_right _ IH).le.trans
        rw [add_succ m, add_succ _ 8, succ_eq_add_one, succ_eq_add_one,
            ack_succ_succ (_ + 8), add_assoc]
        exact ack_mono_left _ (Nat.add_le_add (le_max_right a b) le_rfl)
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals cases' IHf with a ha; cases' IHg with b hb
  -- Pairing:
  · refine'
      ⟨max a b + 3, fun n =>
        (pair_lt_max_add_one_sq _ _).trans_le <|
          (Nat.pow_le_pow_left (add_le_add_right _ _) 2).trans <|
            ack_add_one_sq_lt_ack_add_three _ _⟩
    rw [max_ack_left]
    exact max_le_max (ha n).le (hb n).le
  -- Composition:
  · exact
      ⟨max a b + 2, fun n =>
        (ha _).trans <| (ack_strictMono_right a <| hb n).trans <| ack_ack_lt_ack_max_add_two a b n⟩
  -- Primitive recursion operator:
  · -- We prove this simpler inequality first.
    have :
      ∀ {m n},
        rec (f m) (fun y IH => g <| pair m <| pair y IH) n < ack (max a b + 9) (m + n) := by
      

Proof state:
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
a : ℕ
ha : ∀ (n : ℕ), f n < ack a n
b : ℕ
hb : ∀ (n : ℕ), g n < ack b n
⊢ ∀ {m n : ℕ}, rec (f m) (fun y IH => g (pair m (pair y IH))) n < ack (max a b + 9) (m + n)

Next tactic:
intro m n
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals cases' IHf with a ha; cases' IHg with b hb
  -- Pairing:
  · refine'
      ⟨max a b + 3, fun n =>
        (pair_lt_max_add_one_sq _ _).trans_le <|
          (Nat.pow_le_pow_left (add_le_add_right _ _) 2).trans <|
            ack_add_one_sq_lt_ack_add_three _ _⟩
    rw [max_ack_left]
    exact max_le_max (ha n).le (hb n).le
  -- Composition:
  · exact
      ⟨max a b + 2, fun n =>
        (ha _).trans <| (ack_strictMono_right a <| hb n).trans <| ack_ack_lt_ack_max_add_two a b n⟩
  -- Primitive recursion operator:
  · -- We prove this simpler inequality first.
    have :
      ∀ {m n},
        rec (f m) (fun y IH => g <| pair m <| pair y IH) n < ack (max a b + 9) (m + n) := by
      intro m n
      -- We induct on n.
      

Proof state:
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
a : ℕ
ha : ∀ (n : ℕ), f n < ack a n
b : ℕ
hb : ∀ (n : ℕ), g n < ack b n
m n : ℕ
⊢ rec (f m) (fun y IH => g (pair m (pair y IH))) n < ack (max a b + 9) (m + n)

Next tactic:
induction' n with n IH
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals cases' IHf with a ha; cases' IHg with b hb
  -- Pairing:
  · refine'
      ⟨max a b + 3, fun n =>
        (pair_lt_max_add_one_sq _ _).trans_le <|
          (Nat.pow_le_pow_left (add_le_add_right _ _) 2).trans <|
            ack_add_one_sq_lt_ack_add_three _ _⟩
    rw [max_ack_left]
    exact max_le_max (ha n).le (hb n).le
  -- Composition:
  · exact
      ⟨max a b + 2, fun n =>
        (ha _).trans <| (ack_strictMono_right a <| hb n).trans <| ack_ack_lt_ack_max_add_two a b n⟩
  -- Primitive recursion operator:
  · -- We prove this simpler inequality first.
    have :
      ∀ {m n},
        rec (f m) (fun y IH => g <| pair m <| pair y IH) n < ack (max a b + 9) (m + n) := by
      intro m n
      -- We induct on n.
      induction' n with n IH
      -- The base case is easy.
      · 

Proof state:
case zero
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
a : ℕ
ha : ∀ (n : ℕ), f n < ack a n
b : ℕ
hb : ∀ (n : ℕ), g n < ack b n
m : ℕ
⊢ rec (f m) (fun y IH => g (pair m (pair y IH))) zero < ack (max a b + 9) (m + zero)

Next tactic:
apply (ha m).trans (ack_strictMono_left m <| (le_max_left a b).trans_lt _)
/-- If `f` is primitive recursive, there exists `m` such that `f n < ack m n` for all `n`. -/
theorem exists_lt_ack_of_nat_primrec {f : ℕ → ℕ} (hf : Nat.Primrec f) :
    ∃ m, ∀ n, f n < ack m n := by
  induction' hf with f g hf hg IHf IHg f g hf hg IHf IHg f g hf hg IHf IHg
  -- Zero function:
  · exact ⟨0, ack_pos 0⟩
  -- Successor function:
  · refine' ⟨1, fun n => _⟩
    rw [succ_eq_one_add]
    apply add_lt_ack
  -- Left projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_left_le n
  -- Right projection:
  · refine' ⟨0, fun n => _⟩
    rw [ack_zero, lt_succ_iff]
    exact unpair_right_le n
  all_goals cases' IHf with a ha; cases' IHg with b hb
  -- Pairing:
  · refine'
      ⟨max a b + 3, fun n =>
        (pair_lt_max_add_one_sq _ _).trans_le <|
          (Nat.pow_le_pow_left (add_le_add_right _ _) 2).trans <|
            ack_add_one_sq_lt_ack_add_three _ _⟩
    rw [max_ack_left]
    exact max_le_max (ha n).le (hb n).le
  -- Composition:
  · exact
      ⟨max a b + 2, fun n =>
        (ha _).trans <| (ack_strictMono_right a <| hb n).trans <| ack_ack_lt_ack_max_add_two a b n⟩
  -- Primitive recursion operator:
  · -- We prove this simpler inequality first.
    have :
      ∀ {m n},
        rec (f m) (fun y IH => g <| pair m <| pair y IH) n < ack (max a b + 9) (m + n) := by
      intro m n
      -- We induct on n.
      induction' n with n IH
      -- The base case is easy.
      · apply (ha m).trans (ack_strictMono_left m <| (le_max_left a b).trans_lt _)
        

Proof state:
f✝ f g : ℕ → ℕ
hf : Nat.Primrec f
hg : Nat.Primrec g
a : ℕ
ha : ∀ (n : ℕ), f n < ack a n
b : ℕ
hb : ∀ (n : ℕ), g n < ack b n
m : ℕ
⊢ max a b < max a b + 9

Next tactic:
linarith