MaxLeafFormal.CCT

Source file MaxLeafFormal/CCT.lean of the Lean project (how it is built).

Statements of the paper formalised here: Corollary 11.5.

import MaxLeafFormal.MLS
import MaxLeafFormal.CCRate
import MaxLeafFormal.CCGibbs

/-!
# `cor:cc-T`(a): the generating function of a component-count running time

The paper's `def:cc-bound` and part (a) of `cor:cc-T`, with its proof.

`W_ge_Z` is step 1 (no tree needed, `y ≥ 0`), `cc_T_a_of_gibbs` is part (a) with the Gibbs
inequality as a hypothesis, and `cc_T_a` is part (a) as stated, using `CCGibbs.cc_gibbs`.
-/

namespace MaxLeafFormal.CCT

open Finset

variable {U : Type*} [Fintype U] [DecidableEq U]

/-- `eq:cc-bound` for the solution `S` of size `k`, the tree `F` on `S` and constants `c, γ`. -/
def CCBoundOn (g : Finset U → ℕ → ℝ) (S : Finset U) (k : ℕ) (c γ : ℝ) (F : SimpleGraph S) : Prop :=
  ∀ X ⊆ S, g X (k - X.card) ≤
    ((k : ℝ) - X.card) * Real.logb 2 c + X.card - (CCGibbs.eIn F (X.subtype (· ∈ S)) : ℝ) + γ

/-- `def:cc-bound` for one fixed instance: every solution of size at least 1 has a tree. -/
def HasCCBound (sol : Finset U → Prop) (g : Finset U → ℕ → ℝ) (c γ : ℝ) : Prop :=
  1 ≤ c ∧ 0 ≤ γ ∧
    ∀ S : Finset U, sol S → 1 ≤ S.card → ∃ F : SimpleGraph S, F.IsTree ∧ CCBoundOn g S S.card c γ F

/-! ### Real-number helpers -/

/-- `λ_max(M_ζ) ≥ 1` for `ζ ≥ 0`. -/
theorem one_le_spr {ζ : ℝ} (hζ : 0 ≤ ζ) : 1 ≤ CCRate.spr ζ := by
  unfold CCRate.spr
  have h : 1 ≤ Real.sqrt (1 + 4 * ζ ^ 2) := by
    calc (1:ℝ) = Real.sqrt 1 := Real.sqrt_one.symm
      _ ≤ Real.sqrt (1 + 4 * ζ ^ 2) := Real.sqrt_le_sqrt (by nlinarith)
  linarith

/-- `2^{m log₂ c} = c^m` for `c > 0`. -/
theorem rpow_logb_mul_nat {c : ℝ} (hc : 0 < c) (m : ℕ) :
    (2:ℝ) ^ ((m : ℝ) * Real.logb 2 c) = c ^ m := by
  rw [mul_comm, Real.rpow_mul (by norm_num : (0:ℝ) ≤ 2),
    Real.rpow_logb (by norm_num) (by norm_num) hc, Real.rpow_natCast]

/-- The termwise bound of step 1. -/
theorem termwise {c γ y gx : ℝ} (hc : 0 < c) (hy : 0 ≤ y) {k x e : ℕ} (hxk : x ≤ k)
    (hb : gx ≤ ((k : ℝ) - x) * Real.logb 2 c + x - (e : ℝ) + γ) :
    (2:ℝ) ^ (-γ) * (c ^ k)⁻¹ * ((c * y / 2) ^ x * (2:ℝ) ^ e) ≤ y ^ x * (2:ℝ) ^ (-gx) := by
  set E := ((k : ℝ) - x) * Real.logb 2 c + x - (e : ℝ) + γ with hE
  have hmono : (2:ℝ) ^ (-E) ≤ (2:ℝ) ^ (-gx) :=
    Real.rpow_le_rpow_of_exponent_le (by norm_num) (by linarith)
  have hkey : (2:ℝ) ^ (-E) * (c ^ (k - x) * 2 ^ x) = (2:ℝ) ^ (-γ) * 2 ^ e := by
    rw [← rpow_logb_mul_nat hc, ← Real.rpow_natCast (2:ℝ) x, ← Real.rpow_natCast (2:ℝ) e]
    simp only [← Real.rpow_add (by norm_num : (0:ℝ) < 2)]
    congr 1
    rw [hE, Nat.cast_sub hxk]
    ring
  have hD : c ^ (k - x) * (2:ℝ) ^ x ≠ 0 := by positivity
  have h2E : (2:ℝ) ^ (-E) = (2:ℝ) ^ (-γ) * 2 ^ e / (c ^ (k - x) * 2 ^ x) := by
    rw [eq_div_iff hD]; exact hkey
  have hc0 : c ≠ 0 := hc.ne'
  calc (2:ℝ) ^ (-γ) * (c ^ k)⁻¹ * ((c * y / 2) ^ x * (2:ℝ) ^ e)
      = y ^ x * (2:ℝ) ^ (-E) := by
        rw [h2E, ← pow_sub_mul_pow c hxk, div_pow, mul_pow]
        field_simp
    _ ≤ y ^ x * (2:ℝ) ^ (-gx) := mul_le_mul_of_nonneg_left hmono (pow_nonneg hy _)

omit [Fintype U] in

/-- `𝒵_F(ζ)` as a sum over the subsets of `S`. -/
theorem Zpart_eq_sum_powerset (S : Finset U) (F : SimpleGraph S) (ζ : ℝ) :
    CCGibbs.Zpart F ζ =
      ∑ X ∈ S.powerset, ζ ^ X.card * (2:ℝ) ^ CCGibbs.eIn F (X.subtype (· ∈ S)) := by
  unfold CCGibbs.Zpart
  refine Finset.sum_nbij' (fun X' => X'.map (Function.Embedding.subtype (· ∈ S)))
    (fun X => X.subtype (· ∈ S)) ?_ ?_ ?_ ?_ ?_
  · intro X' _
    rw [Finset.mem_powerset]
    intro a ha
    rw [Finset.mem_map] at ha
    obtain ⟨b, _, rfl⟩ := ha
    exact b.2
  · intro X _
    exact Finset.mem_powerset.mpr (Finset.subset_univ _)
  · intro X' _
    ext b
    simp
  · intro X hX
    exact Finset.subtype_map_of_mem (fun x hx => Finset.mem_powerset.mp hX hx)
  · intro X' _
    have h : (X'.map (Function.Embedding.subtype (· ∈ S))).subtype (· ∈ S) = X' := by
      ext b
      simp
    rw [h, Finset.card_map]

/-! ### Step 1 -/

/-- Step 1 (first inequality of `cor:cc-T`(a)). No tree hypothesis; `y ≥ 0` suffices. -/
theorem W_ge_Z (g : Finset U → ℕ → ℝ) (S : Finset U) (k : ℕ) (hSk : S.card = k)
    (c γ : ℝ) (hc : 1 ≤ c) (F : SimpleGraph S) (hbound : CCBoundOn g S k c γ F)
    (y : ℝ) (hy : 0 ≤ y) :
    (2:ℝ) ^ (-γ) * (c ^ k)⁻¹ * CCGibbs.Zpart F (c * y / 2) ≤ MLS.W g S k y := by
  rw [Zpart_eq_sum_powerset, Finset.mul_sum]
  unfold MLS.W
  refine Finset.sum_le_sum fun X hX => ?_
  have hXS : X ⊆ S := Finset.mem_powerset.mp hX
  have hxk : X.card ≤ k := hSk ▸ Finset.card_le_card hXS
  exact termwise (by linarith) hy hxk (hbound X hXS)

/-! ### Step 2 -/

/-- The rescaled Gibbs inequality, graph-free. -/
theorem gibbs_rescale {c l m Z : ℝ} (hc : 0 < c) (hl : 0 < l) {k : ℕ} (hk : 1 ≤ k)
    (h : m * l ^ (k - 1) ≤ Z) : m / l * (l / c) ^ k ≤ (c ^ k)⁻¹ * Z := by
  have heq : m / l * (l / c) ^ k = (c ^ k)⁻¹ * (m * l ^ (k - 1)) := by
    obtain ⟨j, rfl⟩ : ∃ j, k = j + 1 := ⟨k - 1, by omega⟩
    rw [Nat.add_sub_cancel, div_pow, pow_succ]
    field_simp
  rw [heq]
  exact mul_le_mul_of_nonneg_left h (inv_nonneg.mpr (pow_nonneg hc.le _))

/-! ### Part (a) -/

/-- `cor:cc-T`(a), with `lem:cc-gibbs` for this `F` and `ζ = cy/2` as the hypothesis `hG`. -/
theorem cc_T_a_of_gibbs (g : Finset U → ℕ → ℝ) (S : Finset U) (k : ℕ) (hSk : S.card = k)
    (hk : 1 ≤ k) (c γ : ℝ) (hc : 1 ≤ c) (F : SimpleGraph S) (hbound : CCBoundOn g S k c γ F)
    (y : ℝ) (hy : 0 < y)
    (hG : min 1 (c * y / 2) * CCRate.spr (c * y / 2) ^ (k - 1) ≤ CCGibbs.Zpart F (c * y / 2)) :
    (2:ℝ) ^ (-γ) * (c ^ k)⁻¹ * CCGibbs.Zpart F (c * y / 2) ≤ MLS.W g S k y ∧
    (2:ℝ) ^ (-γ) * (min 1 (c * y / 2) / CCRate.spr (c * y / 2)) * (CCRate.spr (c * y / 2) / c) ^ k
      ≤ (2:ℝ) ^ (-γ) * (c ^ k)⁻¹ * CCGibbs.Zpart F (c * y / 2) ∧
    (1 + y) ^ Fintype.card U / MLS.W g S k y
      ≤ (2:ℝ) ^ γ * (CCRate.spr (c * y / 2) / min 1 (c * y / 2)) *
          (2:ℝ) ^ ((Fintype.card U : ℝ) * CCRate.phi c ((k : ℝ) / Fintype.card U) y) := by
  have hc0 : 0 < c := by linarith
  have hζ : 0 < c * y / 2 := by positivity
  have hl1 : 1 ≤ CCRate.spr (c * y / 2) := one_le_spr hζ.le
  have hl : 0 < CCRate.spr (c * y / 2) := by linarith
  have hm : 0 < min 1 (c * y / 2) := lt_min one_pos hζ
  have h2γ : (0:ℝ) < (2:ℝ) ^ (-γ) := Real.rpow_pos_of_pos (by norm_num) _
  have hA := W_ge_Z g S k hSk c γ hc F hbound y hy.le
  have hB : (2:ℝ) ^ (-γ) * (min 1 (c * y / 2) / CCRate.spr (c * y / 2)) *
      (CCRate.spr (c * y / 2) / c) ^ k
      ≤ (2:ℝ) ^ (-γ) * (c ^ k)⁻¹ * CCGibbs.Zpart F (c * y / 2) := by
    have h := gibbs_rescale hc0 hl hk hG
    calc (2:ℝ) ^ (-γ) * (min 1 (c * y / 2) / CCRate.spr (c * y / 2)) *
          (CCRate.spr (c * y / 2) / c) ^ k
        = (2:ℝ) ^ (-γ) * (min 1 (c * y / 2) / CCRate.spr (c * y / 2) *
          (CCRate.spr (c * y / 2) / c) ^ k) := by ring
      _ ≤ (2:ℝ) ^ (-γ) * ((c ^ k)⁻¹ * CCGibbs.Zpart F (c * y / 2)) :=
          mul_le_mul_of_nonneg_left h h2γ.le
      _ = (2:ℝ) ^ (-γ) * (c ^ k)⁻¹ * CCGibbs.Zpart F (c * y / 2) := by ring
  refine ⟨hA, hB, ?_⟩
  -- Step 3.
  have hkn : k ≤ Fintype.card U := hSk ▸ Finset.card_le_univ S
  have hn : (Fintype.card U : ℝ) ≠ 0 := by
    have : 0 < Fintype.card U := by omega
    positivity
  have hR : 0 < (2:ℝ) ^ (-γ) * (min 1 (c * y / 2) / CCRate.spr (c * y / 2)) *
      (CCRate.spr (c * y / 2) / c) ^ k := by positivity
  have hRW := le_trans hB hA
  have h1y : (0:ℝ) < 1 + y := by linarith
  have hlc : 0 < CCRate.spr (c * y / 2) / c := div_pos hl hc0
  have hnk : (Fintype.card U : ℝ) * ((k : ℝ) / Fintype.card U) = k := by field_simp
  have hphi : (2:ℝ) ^ ((Fintype.card U : ℝ) * CCRate.phi c ((k : ℝ) / Fintype.card U) y)
      = (1 + y) ^ Fintype.card U / (CCRate.spr (c * y / 2) / c) ^ k := by
    unfold CCRate.phi
    rw [mul_sub, ← mul_assoc, hnk, Real.rpow_sub (by norm_num : (0:ℝ) < 2),
      rpow_logb_mul_nat h1y, rpow_logb_mul_nat hlc]
  calc (1 + y) ^ Fintype.card U / MLS.W g S k y
      ≤ (1 + y) ^ Fintype.card U / ((2:ℝ) ^ (-γ) * (min 1 (c * y / 2) / CCRate.spr (c * y / 2)) *
          (CCRate.spr (c * y / 2) / c) ^ k) :=
        div_le_div_of_nonneg_left (by positivity) hR hRW
    _ = (2:ℝ) ^ γ * (CCRate.spr (c * y / 2) / min 1 (c * y / 2)) *
          (2:ℝ) ^ ((Fintype.card U : ℝ) * CCRate.phi c ((k : ℝ) / Fintype.card U) y) := by
        rw [hphi, Real.rpow_neg (by norm_num : (0:ℝ) ≤ 2)]
        have h2 : (0:ℝ) < (2:ℝ) ^ γ := Real.rpow_pos_of_pos (by norm_num) _
        field_simp

/-- `cor:cc-T`(a) as stated. It uses `CCGibbs.cc_gibbs`.
`1 ≤ k` is not a binder: it follows from `hF` and `hSk`. -/
theorem cc_T_a (g : Finset U → ℕ → ℝ) (S : Finset U) (k : ℕ) (hSk : S.card = k)
    (c γ : ℝ) (hc : 1 ≤ c) (F : SimpleGraph S) (hF : F.IsTree)
    (hbound : CCBoundOn g S k c γ F) (y : ℝ) (hy : 0 < y) :
    (2:ℝ) ^ (-γ) * (c ^ k)⁻¹ * CCGibbs.Zpart F (c * y / 2) ≤ MLS.W g S k y ∧
    (2:ℝ) ^ (-γ) * (min 1 (c * y / 2) / CCRate.spr (c * y / 2)) * (CCRate.spr (c * y / 2) / c) ^ k
      ≤ (2:ℝ) ^ (-γ) * (c ^ k)⁻¹ * CCGibbs.Zpart F (c * y / 2) ∧
    (1 + y) ^ Fintype.card U / MLS.W g S k y
      ≤ (2:ℝ) ^ γ * (CCRate.spr (c * y / 2) / min 1 (c * y / 2)) *
          (2:ℝ) ^ ((Fintype.card U : ℝ) * CCRate.phi c ((k : ℝ) / Fintype.card U) y) := by
  have hk : 1 ≤ k := by
    obtain ⟨⟨x, hx⟩⟩ := hF.1.nonempty
    rw [← hSk]
    exact Finset.card_pos.mpr ⟨x, hx⟩
  have hζ : 0 < c * y / 2 := by
    have : 0 < c := by linarith
    positivity
  have hG := CCGibbs.cc_gibbs F hF (c * y / 2) hζ
  rw [Fintype.card_coe, hSk] at hG
  exact cc_T_a_of_gibbs g S k hSk hk c γ hc F hbound y hy hG

/-- Optional (stage 2): the form "let `g` have a component-count bound". -/
theorem cc_T_a_of_hasCCBound (sol : Finset U → Prop) (g : Finset U → ℕ → ℝ) (c γ : ℝ)
    (hg : HasCCBound sol g c γ) (S : Finset U) (hS : sol S) (hk : 1 ≤ S.card) :
    ∃ F : SimpleGraph S, F.IsTree ∧ CCBoundOn g S S.card c γ F ∧
      ∀ y : ℝ, 0 < y →
        (2:ℝ) ^ (-γ) * (c ^ S.card)⁻¹ * CCGibbs.Zpart F (c * y / 2) ≤ MLS.W g S S.card y ∧
        (2:ℝ) ^ (-γ) * (min 1 (c * y / 2) / CCRate.spr (c * y / 2)) *
            (CCRate.spr (c * y / 2) / c) ^ S.card
          ≤ (2:ℝ) ^ (-γ) * (c ^ S.card)⁻¹ * CCGibbs.Zpart F (c * y / 2) ∧
        (1 + y) ^ Fintype.card U / MLS.W g S S.card y
          ≤ (2:ℝ) ^ γ * (CCRate.spr (c * y / 2) / min 1 (c * y / 2)) *
              (2:ℝ) ^ ((Fintype.card U : ℝ) *
                CCRate.phi c ((S.card : ℝ) / Fintype.card U) y) := by
  obtain ⟨hc, -, hS'⟩ := hg
  obtain ⟨F, hF, hb⟩ := hS' S hS hk
  exact ⟨F, hF, hb, fun y hy => cc_T_a g S S.card rfl c γ hc F hF hb y hy⟩

end MaxLeafFormal.CCT
Back to top