CubicPathwidth.PwSeq.Extension
Source file CubicPathwidth/PwSeq/Extension.lean of the Lean project (how it is built).
import CubicPathwidth.PwSeq.Defs
/-!
# Lemma 9.6 (`lem:extension`) for general `k` (obligation Q2)
Proves `TargetBootSeq` (the bootstrap sequence is the one defined by Equation (9.1) (`eq:bootstrap-rec`))
and `ExtensionClaim` (the bootstrap of a seed satisfying `SeedHyp` has the properties
`BootPropsK`). In the paper: Lemma 9.6 (`lem:extension`).
With `b = bootstrapSeq k a`, `h_d = b_d - b_{d-1}` and `H_d = min_{3 ≤ i ≤ d} h_i`, the
second component of `bootPair k a d` is `H_d` (`bootPair_snd`). For `d > k`, put
`μ = H_{d-1}` and `θ = (1 - b_{d-1} - μ)/d`; the two terms of the maximum are
`b_{d-1} + θ` and `b_{d-1} + θ + (d-1)(θ - μ)`, and `bootStep_spec` shows in both cases
`h_d ≥ 0`, `H_d ≥ 0` and `1 - b_d = (d-1) H_d + H_{d-1}`.
-/
noncomputable section
namespace CubicPathwidth
namespace PwSeq
/-! ## One step of the recurrence -/
/-- One step of the recurrence, as a statement about reals. -/
theorem bootStep_spec (d : ℕ) (hd : 3 ≤ d) (bp μ : ℝ) (hμ : 0 ≤ μ) (hb : bp + μ ≤ 1) :
bp ≤ bootStep d bp μ ∧ 0 ≤ min μ (bootStep d bp μ - bp) ∧
1 - bootStep d bp μ = ((d : ℝ) - 1) * min μ (bootStep d bp μ - bp) + μ := by
have hd' : (3 : ℝ) ≤ d := by exact_mod_cast hd
have hdpos : (0 : ℝ) < d := by linarith
set θ : ℝ := (1 - bp - μ) / d with hθdef
have hθ : (d : ℝ) * θ = 1 - bp - μ := by
rw [hθdef]; field_simp
have hθ0 : 0 ≤ θ := by
rw [hθdef]; exact div_nonneg (by linarith) hdpos.le
have hp : (1 + ((d : ℝ) - 1) * bp - μ) / d = bp + θ := by
rw [hθdef]; field_simp; ring
have hq : 1 - (d : ℝ) * μ = bp + θ + ((d : ℝ) - 1) * (θ - μ) := by
nlinarith
unfold bootStep
rw [hp, hq]
rcases le_total θ μ with h | h
· have hm : max (bp + θ) (bp + θ + ((d : ℝ) - 1) * (θ - μ)) = bp + θ := by
apply max_eq_left
nlinarith
rw [hm]
have : min μ (bp + θ - bp) = θ := by
rw [show bp + θ - bp = θ by ring]; exact min_eq_right h
rw [this]
refine ⟨by linarith, hθ0, ?_⟩
nlinarith
· have hm : max (bp + θ) (bp + θ + ((d : ℝ) - 1) * (θ - μ)) =
bp + θ + ((d : ℝ) - 1) * (θ - μ) := by
apply max_eq_right
nlinarith
rw [hm]
have hge : μ ≤ bp + θ + ((d : ℝ) - 1) * (θ - μ) - bp := by
nlinarith
have : min μ (bp + θ + ((d : ℝ) - 1) * (θ - μ) - bp) = μ := min_eq_left hge
rw [this]
refine ⟨by nlinarith, hμ, ?_⟩
nlinarith
/-! ## Running minima -/
theorem runMin_le_three (b : ℕ → ℝ) (d : ℕ) (hd : d ≤ 3) : runMin b d = incr b 3 := by
match d, hd with
| 0, _ => rfl
| 1, _ => rfl
| 2, _ => rfl
| 3, _ => rfl
theorem runMin_succ (b : ℕ → ℝ) (d : ℕ) (hd : 3 ≤ d) :
runMin b (d + 1) = min (runMin b d) (incr b (d + 1)) := by
obtain ⟨m, rfl⟩ : ∃ m, d = m + 3 := ⟨d - 3, by omega⟩
rfl
/-- For `d ≥ 3`, `runMin b d` only depends on the values of `b` at indices `≤ d`. -/
theorem runMin_congr (b c : ℕ → ℝ) (d : ℕ) (hd : 3 ≤ d) (h : ∀ i, i ≤ d → b i = c i) :
runMin b d = runMin c d := by
induction d, hd using Nat.le_induction with
| base =>
rw [runMin_le_three b 3 le_rfl, runMin_le_three c 3 le_rfl]
simp only [incr]
rw [h 3 le_rfl, h 2 (by omega)]
| succ d hd ih =>
rw [runMin_succ b d hd, runMin_succ c d hd, ih (fun i hi => h i (by omega))]
simp only [incr]
rw [h (d + 1) le_rfl, h (d + 1 - 1) (by omega)]
/-- If all increments `h_3, …, h_d` are nonnegative, so is `H_d` (`d ≥ 3`). -/
theorem runMin_nonneg_of (b : ℕ → ℝ) (d : ℕ) (hd : 3 ≤ d)
(h : ∀ i, 3 ≤ i → i ≤ d → 0 ≤ incr b i) : 0 ≤ runMin b d := by
induction d, hd using Nat.le_induction with
| base => rw [runMin_le_three b 3 le_rfl]; exact h 3 le_rfl le_rfl
| succ d hd ih =>
rw [runMin_succ b d hd]
exact le_min (ih (fun i h3 hi => h i h3 (by omega))) (h (d + 1) (by omega) le_rfl)
/-! ## Structure of `bootPair` and `bootstrapSeq` -/
section
variable (k : ℕ) (a : ℕ → ℝ)
theorem bootstrapSeq_le_two (d : ℕ) (hd : d ≤ 2) : bootstrapSeq k a d = 0 := by
match d, hd with
| 0, _ => rfl
| 1, _ => rfl
| 2, _ => rfl
theorem bootstrapSeq_three : bootstrapSeq k a 3 = a 3 := rfl
theorem bootstrapSeq_succ (m : ℕ) :
bootstrapSeq k a (m + 4) =
if m + 4 ≤ k then a (m + 4)
else bootStep (m + 4) (bootPair k a (m + 3)).1 (bootPair k a (m + 3)).2 := by
simp only [bootstrapSeq, bootPair]
theorem bootPair_succ_snd (m : ℕ) :
(bootPair k a (m + 4)).2 =
min (bootPair k a (m + 3)).2 (bootstrapSeq k a (m + 4) - bootstrapSeq k a (m + 3)) := by
simp only [bootstrapSeq, bootPair]
/-- The second component of `bootPair k a d` is the running minimum of the increments. -/
theorem bootPair_snd (d : ℕ) (hd : 3 ≤ d) :
(bootPair k a d).2 = runMin (bootstrapSeq k a) d := by
induction d, hd using Nat.le_induction with
| base =>
rw [runMin_le_three _ 3 le_rfl]
simp only [bootPair, incr, bootstrapSeq_le_two k a 2 le_rfl]
simp [bootstrapSeq_three]
| succ d hd ih =>
obtain ⟨m, rfl⟩ : ∃ m, d = m + 3 := ⟨d - 3, by omega⟩
rw [show m + 3 + 1 = m + 4 by rfl, bootPair_succ_snd, ih]
rfl
theorem bootstrapSeq_seed (d : ℕ) (h3 : 3 ≤ d) (hdk : d ≤ k) :
bootstrapSeq k a d = a d := by
obtain ⟨m, rfl⟩ : ∃ m, d = m + 3 := ⟨d - 3, by omega⟩
rcases m with _ | m
· rfl
· rw [show m + 1 + 3 = m + 4 by rfl, bootstrapSeq_succ]
simp only [show m + 4 ≤ k by omega, ↓reduceIte]
theorem bootstrapSeq_gt (d : ℕ) (hdk : k < d) (hk : 3 ≤ k) :
bootstrapSeq k a d =
bootStep d (bootstrapSeq k a (d - 1)) (runMin (bootstrapSeq k a) (d - 1)) := by
obtain ⟨m, rfl⟩ : ∃ m, d = m + 4 := ⟨d - 4, by omega⟩
rw [bootstrapSeq_succ]
simp only [show ¬ (m + 4 ≤ k) by omega, ↓reduceIte]
rw [show m + 4 - 1 = m + 3 by rfl, bootPair_snd k a (m + 3) (by omega)]
rfl
end
/-- (A3) `bootstrapSeq` is the sequence defined by Equation (9.1) (`eq:bootstrap-rec`). -/
theorem targetBootSeq : TargetBootSeq := by
intro k a hk
exact ⟨bootstrapSeq_le_two k a, fun d h3 hdk => bootstrapSeq_seed k a d h3 hdk,
fun d hdk => bootstrapSeq_gt k a d hdk hk⟩
/-! ## The extension lemma -/
theorem extension : ExtensionClaim := by
intro k a hseed
obtain ⟨hk, ha3, hmono, hbud⟩ := hseed
set b : ℕ → ℝ := bootstrapSeq k a with hbdef
have hseedb : ∀ d, 3 ≤ d → d ≤ k → b d = a d := fun d h3 hdk =>
bootstrapSeq_seed k a d h3 hdk
have hb0 : ∀ d, d ≤ 2 → b d = 0 := fun d hd => bootstrapSeq_le_two k a d hd
have hb2 : b 2 = 0 := hb0 2 le_rfl
have hgt : ∀ d, k < d → b d = bootStep d (b (d - 1)) (runMin b (d - 1)) := fun d hdk =>
bootstrapSeq_gt k a d hdk hk
-- increments up to `k` are nonnegative
have hinc : ∀ i, 3 ≤ i → i ≤ k → 0 ≤ incr b i := by
intro i h3 hik
simp only [incr]
rcases Nat.eq_or_lt_of_le h3 with rfl | h4
· rw [hseedb 3 le_rfl hik, hb2]; simpa using ha3
· rw [hseedb i h3 hik, hseedb (i - 1) (by omega) (by omega)]
have := hmono (i - 1) (by omega) (by omega)
rw [show i - 1 + 1 = i by omega] at this
linarith
have hH0 : 0 ≤ runMin b k := runMin_nonneg_of b k hk hinc
-- budget at `k`
have hbk : b k + runMin b k ≤ 1 := by
have e : runMin (seedSeq a) k = runMin b k := by
apply runMin_congr _ _ k hk
intro i hi
by_cases h2 : i ≤ 2
· simp [seedSeq, h2, bootstrapSeq_le_two k a i h2, hbdef]
· simp only [seedSeq, h2, ↓reduceIte]
exact (hseedb i (by omega) hi).symm
rw [hseedb k hk le_rfl, ← e]
exact hbud
-- invariant for `d ≥ k`
have hinv : ∀ d, k ≤ d → 0 ≤ runMin b d ∧ b d + runMin b d ≤ 1 := by
intro d hd
induction d, hd using Nat.le_induction with
| base => exact ⟨hH0, hbk⟩
| succ d hd ih =>
have hd3 : 3 ≤ d := by omega
obtain ⟨h1, h2, h3⟩ := bootStep_spec (d + 1) (by omega) (b (d + 1 - 1))
(runMin b (d + 1 - 1)) (by simpa using ih.1) (by simpa using ih.2)
have e : b (d + 1) = bootStep (d + 1) (b d) (runMin b d) := by
simpa using hgt (d + 1) (by omega)
rw [show d + 1 - 1 = d by omega, ← e] at h1 h2 h3
have hr : runMin b (d + 1) = min (runMin b d) (b (d + 1) - b d) := by
rw [runMin_succ b d hd3]; simp [incr]
rw [hr]
refine ⟨h2, ?_⟩
have hd1 : (1 : ℝ) ≤ (d + 1 : ℕ) - 1 := by
have : (1 : ℝ) ≤ d := by exact_mod_cast (by omega : 1 ≤ d)
push_cast; linarith
nlinarith [ih.1]
-- step facts for `d > k`
have hstep : ∀ d, k < d → b (d - 1) ≤ b d ∧
1 - b d = ((d : ℝ) - 1) * runMin b d + runMin b (d - 1) := by
intro d hdk
obtain ⟨m, rfl⟩ : ∃ m, d = m + 1 := ⟨d - 1, by omega⟩
simp only [Nat.add_sub_cancel]
have ih := hinv m (by omega)
obtain ⟨h1, h2, h3⟩ := bootStep_spec (m + 1) (by omega) (b m) (runMin b m) ih.1
(by linarith [ih.2])
have e : b (m + 1) = bootStep (m + 1) (b m) (runMin b m) := by
simpa using hgt (m + 1) hdk
rw [← e] at h1 h2 h3
have hr : runMin b (m + 1) = min (runMin b m) (b (m + 1) - b m) := by
rw [runMin_succ b m (by omega)]; simp [incr]
rw [hr]
refine ⟨h1, ?_⟩
push_cast at h3 ⊢
linarith
have hmonoAll : ∀ d, 3 ≤ d → b (d - 1) ≤ b d := by
intro d h3
by_cases hdk : d ≤ k
· have := hinc d h3 hdk
simp only [incr] at this
linarith
· exact (hstep d (by omega)).1
have hchain : ∀ i j, 3 ≤ i → i ≤ j → b i ≤ b j := by
intro i j hi hij
induction j, hij using Nat.le_induction with
| base => exact le_rfl
| succ j hj ih =>
have := hmonoAll (j + 1) (by omega)
simp only [Nat.add_sub_cancel] at this
linarith
have hHall : ∀ d, 0 ≤ runMin b d := by
intro d
by_cases h3 : 3 ≤ d
· apply runMin_nonneg_of b d h3
intro i hi _
have := hmonoAll i hi
simp only [incr]
linarith
· rw [runMin_le_three b d (by omega)]
have := hmonoAll 3 le_rfl
simp only [incr]
linarith
refine ⟨hk, ⟨hb0 0 (by omega), hb0 1 (by omega), hb2⟩, hmonoAll, ?_, ?_, ?_, fun d => ?_⟩
· intro d hd
simp only [← runMin_eq_t4]
exact (hstep d (by omega)).2
· intro d hd
simp only [← runMin_eq_t4]
exact (hinv d hd).2
· intro d
simp only [← runMin_eq_t4]
exact hHall d
by_cases hdk : d ≤ k
· by_cases h2 : d ≤ 2
· rw [hb0 d h2]; norm_num
· have := hchain d k (by omega) hdk
have := hbk
have := hHall k
linarith
· have := (hinv d (by omega)).2
have := hHall d
linarith
end PwSeq
end CubicPathwidth
#print axioms CubicPathwidth.PwSeq.targetBootSeq
#print axioms CubicPathwidth.PwSeq.extension
Back to top