import Erdos1135.ND.Discrepancy.A5ReferenceSection3AmbientTerminal

/-!
# All-source A5 `T^*`-to-`L^*` no-hit estimate

This leaf exposes the Section 3 terminal trace in the source-facing odd
logarithmic block.  It absorbs the finitely many targets below the ambient
cutoff into one constant and handles sources whose upper endpoint is already
below the target at iterate zero.
-/

namespace Erdos1135
namespace ND

noncomputable section

/-- The natural no-hit probability in a Tao `N_y` window is the same PMF
probability in the ND `oddBlock` convention. -/
private theorem
    syracuseNoHitWindowProb_taoNy_eq_pmfProb_logOddBlockPMF
    (B : Nat) (y : Real)
    (hmassTao :
      0 < Tao.logFinsetMass
        (Tao.oddLogWindow
          (Tao.taoNyLo y) (Tao.taoNyHi y Tao.taoAlpha)))
    (hmassND : 0 < Tao.logFinsetMass (oddBlock y)) :
    Tao.syracuseNoHitWindowProb B
        (Tao.taoNyLo y) (Tao.taoNyHi y Tao.taoAlpha)
        hmassTao =
      Tao.pmfProb (logOddBlockPMF y hmassND)
        {N | ¬ Tao.syracuseHitsAtMost N.1 B} := by
  unfold Tao.syracuseNoHitWindowProb Tao.syracuseNoHitAtMost
    Tao.oddLogWindowPMF logOddBlockPMF oddBlock Tao.taoNyOddWindow
  rfl

/-- Starting the ambient trace at `X = y^alpha` makes its terminal boundary
exactly `y`. -/
private theorem taoSection3AmbientBoundary_rpow_taoAlpha_one
    {y : Real} (hy : 0 <= y) :
    Tao.taoSection3AmbientBoundary (y ^ Tao.taoAlpha) 1 = y := by
  simpa only [Tao.taoSection3AmbientBoundary,
    Tao.taoSection3AmbientRatio, pow_one] using
      Real.rpow_rpow_inv hy Tao.taoAlpha_pos.ne'

/-- If the upper endpoint of the source block is at most `B`, every source
hits the target at iterate zero. -/
private theorem syracuseHitsAtMost_of_mem_oddBlock_of_rpow_le
    {B : Nat} {y : Real} (hy : 0 <= y)
    (hupper : y ^ Tao.taoAlpha <= (B : Real))
    {N : Nat} (hN : N ∈ oddBlock y) :
    Tao.syracuseHitsAtMost N B := by
  have hNwindow :
      N ∈ Tao.taoNyOddWindow y Tao.taoAlpha := by
    simpa only [oddBlock, alpha] using hN
  have hNleReal : (N : Real) <= y ^ Tao.taoAlpha :=
    ((Tao.taoNyOddWindow_mem
      (alpha := Tao.taoAlpha) hy).mp hNwindow).2.1
  have hNB : N <= B := by
    exact_mod_cast hNleReal.trans hupper
  exact ⟨0, by
    simpa only [Function.iterate_zero, id_eq] using hNB⟩

/-- The fixed-target Section 3 trace, with all ambient cutoffs hidden, holds
uniformly for every natural target and every positive odd logarithmic source
block.  The constant is selected before `N0`, `y`, and the source-mass proof.
-/
theorem exists_ndA5ReferenceAllSourceTStarL
    {c kappa d : Real} (hPhase : PhaseGap c kappa)
    (hd : 0 < d) (hd20 : d < 1 / 20)
    (hdk : d < 1 / (2 * kappa)) :
    ∃ C : Real, 0 <= C ∧
      ∀ (N0 : Nat), 2 <= N0 ->
        ∀ (y : Real), 2 <= y ->
          ∀ hmass : 0 < Tao.logFinsetMass (oddBlock y),
            Tao.pmfProb (logOddBlockPMF y hmass)
                {N | N0 < syracuseOrbitMin N.1} <=
              C * (Real.log (N0 : Real)) ^ (-d) := by
  rcases exists_ndA5ReferenceSection3AmbientTerminal
      hPhase hd hd20 hdk with
    ⟨Bstar, hBstar, hCtrace, hterminal⟩
  let Ctrace := ndA5ReferenceSection3AmbientTraceConstant d
  let Csmall := (Real.log (Bstar : Real)) ^ d
  let C := max Ctrace Csmall
  have hBstarOne : (1 : Real) < (Bstar : Real) := by
    exact_mod_cast (show 1 < Bstar by omega)
  have hlogBstarPos : 0 < Real.log (Bstar : Real) :=
    Real.log_pos hBstarOne
  have hCsmall : 0 <= Csmall :=
    Real.rpow_nonneg hlogBstarPos.le d
  have hCtrace' : 0 <= Ctrace := by
    simpa only [Ctrace] using hCtrace
  have hC : 0 <= C := by
    exact hCtrace'.trans (le_max_left Ctrace Csmall)
  refine ⟨C, hC, ?_⟩
  intro N0 hN0 y hy hmass
  have hN0One : (1 : Real) < (N0 : Real) := by
    exact_mod_cast (show 1 < N0 by omega)
  have hlogN0Pos : 0 < Real.log (N0 : Real) :=
    Real.log_pos hN0One
  have hrateNonneg :
      0 <= (Real.log (N0 : Real)) ^ (-d) :=
    Real.rpow_nonneg hlogN0Pos.le (-d)
  by_cases hsmall : N0 < Bstar
  · have hN0leBstar : N0 <= Bstar := hsmall.le
    have hcastLe : (N0 : Real) <= (Bstar : Real) := by
      exact_mod_cast hN0leBstar
    have hlogLe :
        Real.log (N0 : Real) <= Real.log (Bstar : Real) :=
      Real.log_le_log
        (Nat.cast_pos.mpr (show 0 < N0 by omega)) hcastLe
    have hpowLe :
        (Real.log (N0 : Real)) ^ d <=
          (Real.log (Bstar : Real)) ^ d :=
      Real.rpow_le_rpow hlogN0Pos.le hlogLe hd.le
    have hcancel :
        (Real.log (N0 : Real)) ^ d *
            (Real.log (N0 : Real)) ^ (-d) = 1 := by
      rw [← Real.rpow_add hlogN0Pos]
      norm_num
    have hOneSmall :
        1 <= Csmall * (Real.log (N0 : Real)) ^ (-d) := by
      calc
        1 = (Real.log (N0 : Real)) ^ d *
            (Real.log (N0 : Real)) ^ (-d) := hcancel.symm
        _ <= (Real.log (Bstar : Real)) ^ d *
            (Real.log (N0 : Real)) ^ (-d) :=
          mul_le_mul_of_nonneg_right hpowLe hrateNonneg
        _ = Csmall * (Real.log (N0 : Real)) ^ (-d) := by
          rfl
    have hsmallToC :
        Csmall * (Real.log (N0 : Real)) ^ (-d) <=
          C * (Real.log (N0 : Real)) ^ (-d) :=
      mul_le_mul_of_nonneg_right
        (le_max_right Ctrace Csmall) hrateNonneg
    calc
      Tao.pmfProb (logOddBlockPMF y hmass)
          {N | N0 < syracuseOrbitMin N.1} <=
          Tao.pmfProb (logOddBlockPMF y hmass) Set.univ :=
        Tao.pmfProb_mono _ (Set.subset_univ _)
      _ = 1 := Tao.pmfProb_univ _
      _ <= Csmall * (Real.log (N0 : Real)) ^ (-d) := hOneSmall
      _ <= C * (Real.log (N0 : Real)) ^ (-d) := hsmallToC
  · have hBstarN0 : Bstar <= N0 := Nat.le_of_not_gt hsmall
    by_cases hmain : (N0 : Real) < y ^ Tao.taoAlpha
    · rcases hterminal hBstarN0 hmain with
        ⟨hmassAmbient, hterminalBound⟩
      have hy0 : 0 <= y := le_trans (by norm_num) hy
      have hboundary :
          Tao.taoSection3AmbientBoundary
              (y ^ Tao.taoAlpha) 1 = y :=
        taoSection3AmbientBoundary_rpow_taoAlpha_one hy0
      have hmassTao :
          0 < Tao.logFinsetMass
            (Tao.oddLogWindow
              (Tao.taoNyLo y) (Tao.taoNyHi y Tao.taoAlpha)) := by
        simpa only [Tao.taoSection3AmbientWindow,
          Tao.taoNyOddWindow, hboundary] using hmassAmbient
      have htrace :
          Tao.pmfProb (logOddBlockPMF y hmass)
              {N | ¬ Tao.syracuseHitsAtMost N.1 N0} <=
            Ctrace * (Real.log (N0 : Real)) ^ (-d) := by
        rw [← syracuseNoHitWindowProb_taoNy_eq_pmfProb_logOddBlockPMF
          N0 y hmassTao hmass]
        simpa only [hboundary, Ctrace] using hterminalBound
      have htraceOrbit :
          Tao.pmfProb (logOddBlockPMF y hmass)
              {N | N0 < syracuseOrbitMin N.1} <=
            Ctrace * (Real.log (N0 : Real)) ^ (-d) := by
        simpa only [not_syracuseHitsAtMost_iff_lt_orbitMin] using htrace
      exact htraceOrbit.trans
        (mul_le_mul_of_nonneg_right
          (le_max_left Ctrace Csmall) hrateNonneg)
    · have hy0 : 0 <= y := le_trans (by norm_num) hy
      have hupper :
          y ^ Tao.taoAlpha <= (N0 : Real) :=
        le_of_not_gt hmain
      have hempty :
          {N : {n // n ∈ oddBlock y} |
              N0 < syracuseOrbitMin N.1} = ∅ := by
        ext N
        simp only [Set.mem_setOf_eq, Set.mem_empty_iff_false,
          iff_false]
        intro hbad
        have hhit : Tao.syracuseHitsAtMost N.1 N0 :=
          syracuseHitsAtMost_of_mem_oddBlock_of_rpow_le
            hy0 hupper N.property
        exact ((not_syracuseHitsAtMost_iff_lt_orbitMin).2 hbad)
          hhit
      rw [hempty, Tao.pmfProb_empty]
      exact mul_nonneg hC hrateNonneg

end
end ND
end Erdos1135
