Skip to content

feat(Chapter_02): prove all remaining theorems#111

Open
pitmonticone wants to merge 2 commits intomo271:mainfrom
pitmonticone:feat-ch_2
Open

feat(Chapter_02): prove all remaining theorems#111
pitmonticone wants to merge 2 commits intomo271:mainfrom
pitmonticone:feat-ch_2

Conversation

@pitmonticone
Copy link
Contributor

Co-authored-by: aristotle-harmonic@harmonic.fun.
Co-Authored-By: Aristotle <232223898+aristotle-harmonic@users.noreply.github.com>
Copy link
Owner

@mo271 mo271 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, I find these proofs a bit long and suggested shorter ones

Comment on lines +258 to +275
have h_ln : Real.log n.factorial > 1 + n * Real.log n - n := by
induction hn
· have := log_lt_sub_one_of_pos two_pos; norm_num at *; linarith
· norm_num [factorial_succ] at *
rw [log_mul (by positivity) (by positivity)]
have h_log_bound : ∀ m : ℕ, 2 ≤ m → Real.log (m + 1) < Real.log m + 1 / m := by
intro m hm
rw [log_lt_iff_lt_exp (by positivity), exp_add, exp_log (by positivity)]
ring_nf
nlinarith [add_one_lt_exp (by positivity : (m : ℝ) ⁻¹ ≠ 0),
(by norm_cast : (2 : ℝ) ≤ m), mul_inv_cancel₀ (by positivity : (m : ℝ) ≠ 0)]
nlinarith [h_log_bound _ ‹_›, one_div_mul_cancel (by positivity : ((Nat.cast : ℕ → ℝ) ‹_›) ≠ 0)]
have h_exp : (n.factorial : ℝ) > exp (1 + n * Real.log n - n) := by
rwa [gt_iff_lt, lt_log_iff_exp_lt (by positivity)] at h_ln
convert h_exp using 1; norm_num [exp_add, exp_sub, exp_nat_mul, exp_log
(by positivity : 0 < (n : ℝ)), chapter2.e]
ring_nf
norm_num [Real.exp_neg, Real.exp_nat_mul]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
have h_ln : Real.log n.factorial > 1 + n * Real.log n - n := by
induction hn
· have := log_lt_sub_one_of_pos two_pos; norm_num at *; linarith
· norm_num [factorial_succ] at *
rw [log_mul (by positivity) (by positivity)]
have h_log_bound : ∀ m : ℕ, 2 ≤ m → Real.log (m + 1) < Real.log m + 1 / m := by
intro m hm
rw [log_lt_iff_lt_exp (by positivity), exp_add, exp_log (by positivity)]
ring_nf
nlinarith [add_one_lt_exp (by positivity : (m : ℝ) ⁻¹ ≠ 0),
(by norm_cast : (2 : ℝ) ≤ m), mul_inv_cancel₀ (by positivity : (m : ℝ) ≠ 0)]
nlinarith [h_log_bound _ ‹_›, one_div_mul_cancel (by positivity : ((Nat.cast : ℕ → ℝ) ‹_›) ≠ 0)]
have h_exp : (n.factorial : ℝ) > exp (1 + n * Real.log n - n) := by
rwa [gt_iff_lt, lt_log_iff_exp_lt (by positivity)] at h_ln
convert h_exp using 1; norm_num [exp_add, exp_sub, exp_nat_mul, exp_log
(by positivity : 0 < (n : ℝ)), chapter2.e]
ring_nf
norm_num [Real.exp_neg, Real.exp_nat_mul]
refine exp_log (by positivity : rexp 1 * (n / rexp 1)^n > 0) ▸ exp_log.comp Nat.cast_pos.2 n.factorial_pos ▸ Nat.le_induction (?_) ? _ _ hn
· norm_num [(by linear_combination log_two_lt_d9: 1 + (2 * (log 2 - 1)) < log 2), log_mul, log_div]
· field_simp [log_mul,mul_left_comm, log_div, Nat.factorial, pow_succ']
intro n hn h
linear_combination h + ↑n * (by field_simp [←log_div _,((log_le_sub_one_of_pos _)).trans] : log (n + 1)-log n ≤ 1/n) + div_self_le_one (n: ℝ)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mo271 The golfed proof doesn't compile as it is.

Comment on lines +215 to +251
constructor
· induction hn <;> norm_num [harmonic] at *
· norm_num [Finset.sum_range_succ]
linarith [@Real.log_lt_sub_one_of_pos 2 zero_lt_two (OfNat.one_ne_ofNat 2).symm]
· rw [Finset.sum_range_succ]
rename_i k hk ih
rw [show (k : ℝ) + 1 = k * (1 + (k : ℝ) ⁻¹) by
nlinarith only [mul_inv_cancel₀ (by positivity : (k : ℝ) ≠ 0)],
Real.log_mul (by positivity) (by positivity)]
nlinarith [inv_pos.mpr (by positivity : 0 < (k : ℝ)),
inv_pos.mpr (by positivity : 0 < (k : ℝ) * (1 + (k : ℝ) ⁻¹)), mul_inv_cancel₀
(by positivity : (k : ℝ) ≠ 0), mul_inv_cancel₀
(by positivity : (k : ℝ) * (1 + (k : ℝ) ⁻¹) ≠ 0), Real.log_lt_sub_one_of_pos
(by positivity : 0 < (1 + (k : ℝ) ⁻¹))
(by nlinarith [inv_mul_cancel₀ (by positivity : (k : ℝ) ≠ 0)])]
· have h_harmonic : ∀ n : ℕ, 1 < n → (∑ k ∈ Finset.range n, (1 / (k + 1) : ℝ)) < Real.log n + 1 := by
intro n hn
have h_harmonic : ∀ k ∈ Finset.range n, k ≠ 0 → (1 / (k + 1) : ℝ) < Real.log (k + 1) - Real.log k := by
intro k hk hk'; rw [← Real.log_div (by positivity) (by positivity)]; ring_nf
rw [mul_inv_cancel₀ (by positivity), inv_eq_one_div, div_lt_iff₀] <;> nlinarith [Real.log_inv (1 + (k : ℝ) ⁻¹),
Real.log_lt_sub_one_of_pos (inv_pos.mpr (by positivity : 0 < (1 + (k : ℝ) ⁻¹)))
(by aesop), inv_pos.mpr (by positivity : 0 < (1 + (k : ℝ) ⁻¹)), mul_inv_cancel₀
(by positivity : (1 + (k : ℝ) ⁻¹) ≠ 0), inv_pos.mpr (by positivity : 0 < (k : ℝ)),
mul_inv_cancel₀ (by positivity : (k : ℝ) ≠ 0)]
have h_sum : ∑ k ∈ Finset.range n, (1 / (k + 1) : ℝ) < 1 + ∑ k ∈ Finset.range (n - 1), (Real.log (k + 2) - Real.log (k + 1)) := by
rcases n with ⟨⟩ <;> norm_num [add_comm, add_left_comm, Finset.sum_range_succ'] at *
rw [← Finset.sum_sub_distrib]
exact Finset.sum_lt_sum_of_nonempty ⟨_, Finset.mem_range.mpr hn⟩ fun x hx ↦ by
have := h_harmonic (x + 1) (by linarith [Finset.mem_range.mp hx])
(by linarith [Finset.mem_range.mp hx]); norm_num [add_assoc] at *; linarith
have h_telescope :
∑ k ∈ Finset.range (n - 1),
(Real.log (k + 2) - Real.log (k + 1)) = Real.log n - Real.log 1 := by
exact_mod_cast Eq.trans (Finset.sum_range_sub (fun k ↦ Real.log (k + 1)) _)
(by cases n <;> norm_num at *)
norm_num at *; linarith
simpa [harmonic] using h_harmonic n hn
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entier proof could be golfed:

  use(2).le_induction ?_ ? _ _ hn, (2).le_induction ?_ ? _ _ hn
  · norm_num [harmonic, add_lt_of_lt_sub_right ∘ log_two_lt_d9.trans]
  · push_cast [harmonic_succ, one_div]
    intro n hn h
    apply add_lt_add_right (h.trans_le'.comp (sub_le_iff_le_add').mp (by field_simp [← log_div _, (( Real.log_le_sub_one_of_pos _)).trans]))
  · norm_num [harmonic, ←sub_lt_iff_lt_add, log_two_gt_d9.trans']
  · intro n hn h
    apply lt_of_le_of_lt (by rw [harmonic_succ, Rat.cast_add]) ((add_lt_add_right h _).trans_le.comp (add_right_comm _ _ _).trans_le (add_right_mono _))
    exact le_sub_iff_add_le'.1 (by field_simp [le_log_iff_exp_le, (exp_bound_div_one_sub_of_interval' _ _).le.trans, div_lt_self, lt_add_of_pos_left, ←log_div])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mo271 The golfed proof doesn't compile as it is.

@mo271
Copy link
Owner

mo271 commented Jan 1, 2026

In general in the end the proofs should not just work, but follow the informal proofs in the Book...

@mo271
Copy link
Owner

mo271 commented Jan 1, 2026

But it is ok to fill them in now, perhaps I should add a TODO to make them more align with the informal arguments...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants