import Erdos1135.Division
import Mathlib.Analysis.SpecialFunctions.Log.Basic

/-!
# Deterministic lower bounds for raw Collatz time

One raw Collatz step can shrink its input by at most a factor of two.  This
leaf iterates that elementary fact and converts it into logarithmic lower
bounds for any raw orbit that reaches a smaller real threshold.
-/

namespace Erdos1135
namespace Tao

open Function

noncomputable section

/-- A raw Collatz step never shrinks its input by more than a factor of two. -/
theorem le_two_mul_collatzStep (n : ℕ) :
    n ≤ 2 * collatzStep n := by
  by_cases hn : Even n
  · rw [collatzStep_eq_div_two_of_even hn,
      two_mul_div_two_of_even hn]
  · rw [collatzStep_eq_three_mul_add_one_of_not_even hn]
    omega

/-- After `m` raw steps, the starting value is at most `2^m` times the
terminal value.  Equality is attained along an all-even halving segment. -/
theorem le_two_pow_mul_collatz_iterate (m N : ℕ) :
    N ≤ 2 ^ m * (collatzStep^[m]) N := by
  induction m generalizing N with
  | zero => simp
  | succ m ih =>
      calc
        N ≤ 2 * collatzStep N := le_two_mul_collatzStep N
        _ ≤ 2 * (2 ^ m * (collatzStep^[m]) (collatzStep N)) :=
          Nat.mul_le_mul_left 2 (ih (collatzStep N))
        _ = 2 ^ (m + 1) * (collatzStep^[m + 1]) N := by
          rw [pow_succ, Function.iterate_succ_apply]
          ring

/-- Reaching a positive real threshold `b` from a positive source `N` in
`m` raw Collatz steps forces
`(log N - log b) / log 2 < m`.  Positivity of `b` follows from the hit. -/
theorem collatz_hit_time_log_lower
    {N m : ℕ} {b : ℝ} (hN : 0 < N)
    (hhit : ((collatzStep^[m]) N : ℝ) < b) :
    (Real.log (N : ℝ) - Real.log b) / Real.log 2 < (m : ℝ) := by
  have hNreal : 0 < (N : ℝ) := by exact_mod_cast hN
  have hb : 0 < b :=
    lt_of_le_of_lt
      (by positivity : 0 ≤ ((collatzStep^[m]) N : ℝ)) hhit
  have hbound :
      (N : ℝ) ≤ (2 : ℝ) ^ m * ((collatzStep^[m]) N : ℝ) := by
    exact_mod_cast le_two_pow_mul_collatz_iterate m N
  have hstrict : (N : ℝ) < (2 : ℝ) ^ m * b :=
    hbound.trans_lt
      (mul_lt_mul_of_pos_left hhit (pow_pos (by norm_num) m))
  have hlog := Real.log_lt_log hNreal hstrict
  rw [Real.log_mul (pow_ne_zero _ (by norm_num)) hb.ne',
    Real.log_pow] at hlog
  apply (div_lt_iff₀
    (Real.log_pos (by norm_num : (1 : ℝ) < 2))).2
  linarith

/-- For the admissible growing target `sqrt N`, every raw Collatz hit has a
pointwise logarithmic lower bound on its step count. -/
theorem collatz_sqrt_hit_time_lower
    {N m : ℕ} (hN : 0 < N)
    (hhit : ((collatzStep^[m]) N : ℝ) < Real.sqrt (N : ℝ)) :
    Real.log (N : ℝ) / (2 * Real.log 2) < (m : ℝ) := by
  have h := collatz_hit_time_log_lower hN hhit
  rw [Real.log_sqrt (by positivity : (0 : ℝ) ≤ N)] at h
  convert h using 1
  field_simp [ne_of_gt
    (Real.log_pos (by norm_num : (1 : ℝ) < 2))]
  ring

end

end Tao
end Erdos1135
