MaxLeafFormal.RSCCheck
Source file MaxLeafFormal/RSCCheck.lean of the Lean project (how it is built).
import MaxLeafFormal.RSCParams
/-!
# Exact checkers for the RSC certificate
A hand-written mirror of the graded merge and of `Init~` at the RSC constants over natural
numbers with common denominators, and the Boolean checkers that the generated shard theorems run
(by `native_decide`, see `RSCFinal.lean`); their soundness theorems are kernel-checked.
A point is a pair `(N, D)` of eight natural numerators and a positive common denominator; its
value is `N / D`. Working with natural numbers keeps the kernel's work on GMP-accelerated literal
arithmetic (no rational normalisation).
-/
namespace MaxLeafFormal.RSCCheck
/-! ### Computable data -/
/-- Eight natural numerators and a common denominator. -/
abbrev IPt := List ℕ × ℕ
def zeroI : IPt := ([0, 0, 0, 0, 0, 0, 0, 0], 1)
/-- `P ∘̃ Q` at the RSC constants: all coefficients times `1000` are integers
(`2λ = 11/5`, `q₂ = 93/100`, `q₃ = 923/1000`), so the merge has denominator `1000 · D · E`. -/
def mergeN : List ℕ → List ℕ → List ℕ
| [P0, P1, P2, P3, P4, P5, P6, P7], [Q0, _, Q2, Q3, Q4, Q5, Q6, Q7] =>
let S := 2000 * Q0 + 2000 * Q2 + 2200 * Q3 + 1000 * Q4 + 1000 * Q5 + 930 * Q6 + 923 * Q7
let Cs := 2000 * Q0
let Cu := 2000 * Q3 + 1000 * Q4 + 1000 * Q5 + 1000 * Q6 + 930 * Q7
let Os := 1000 * Q0
let Ox := 1000 * Q3
let Ou := 500 * Q4 + 1000 * Q5 + 1000 * Q6 + 930 * Q7
[P0 * S, P1 * Cu, P2 * Cu + P1 * Cs, P3 * (Cu + Cs) + P2 * Cs, P4 * Ou,
P5 * (Ou + Ox) + P4 * Ox, P6 * (Ou + Ox) + (P4 + P5) * Os, P7 * (Ou + Ox + Os) + P6 * Os]
| _, _ => [0, 0, 0, 0, 0, 0, 0, 0]
def mergeI (P Q : IPt) : IPt := (mergeN P.1 Q.1, 1000 * P.2 * Q.2)
/-- `ê = eN / eD`. -/
def eN : ℕ := 145729958
def eD : ℕ := 189014575
/-- `ê^{-1-ν} Init~(ν; c₂, c₃)` at the RSC constants:
`(u·y/2, u·p₂/2, 0, 0, 2^{-ν} ϖ₂^{c₂} ϖ₃^{c₃}, 0, 0, 0) · ê^{-1-ν}` with `u = q₂^{c₂} q₃^{c₃}`,
over the common denominator `eN^{1+ν} · 200 · 100^{c₂} · 1000^{c₃} · 2^ν · 250000^{c₂+c₃}`. -/
def initI (ν c₂ c₃ : ℕ) : IPt :=
let s := eD ^ (1 + ν)
let uN := 93 ^ c₂ * 923 ^ c₃
let uD := 100 ^ c₂ * 1000 ^ c₃
let wN := 272657 ^ c₂ * 288677 ^ c₃
let wD := 2 ^ ν * 250000 ^ (c₂ + c₃)
let D := eN ^ (1 + ν) * 200 * uD * wD
([s * uN * 31 * wD, s * uN * 7 * wD, 0, 0, s * wN * 200 * uD, 0, 0, 0], D)
/-- `ê^{-(ν₀+2)} Init(∞) = ê^{-26} (y/2, p₂/2, 0, …, 0)`. -/
def initInfI : IPt := ([eD ^ 26 * 31, eD ^ 26 * 7, 0, 0, 0, 0, 0, 0], eN ^ 26 * 200)
/-- Membership of an integer vector in `𝒦_pos`, by peeling the leaves of the Hasse tree
(`O₂, O₀₀, C₀, O₁, C₁, O₀₁`). -/
def inK : List ℤ → Bool
| [d0, d1, d2, d3, d4, d5, d6, d7] =>
decide (0 ≤ d0) &&
decide (0 ≤ d3 + min 0 (d2 + min 0 d1) + min 0 (d5 + min 0 d4 + min 0 (d6 + min 0 d7)))
| _ => false
/-- Points in chunks of 32, for fast lookup in the kernel (structural recursion on a fuel bound). -/
def chunksAux : ℕ → List IPt → List (List IPt)
| 0, _ => []
| _, [] => []
| n + 1, l@(_ :: _) => l.take 32 :: chunksAux n (l.drop 32)
def chunks32 (l : List IPt) : List (List IPt) := chunksAux l.length l
def getPt (Yc : List (List IPt)) (k : ℕ) : IPt := (Yc.getD (k / 32) []).getD (k % 32) zeroI
/-- Accumulate `∑ (aₖ/bₖ) · Y[kₖ]` as `(V, T)` with value `V / T`, and the weight sum as `s / t`. -/
def combI (Yc : List (List IPt)) : List (ℕ × ℕ × ℕ) → List ℕ × ℕ × ℕ × ℕ
| [] => ([0, 0, 0, 0, 0, 0, 0, 0], 1, 0, 1)
| (k, a, b) :: cs =>
let r := combI Yc cs
let y := getPt Yc k
(List.zipWith (fun v n => v * (b * y.2) + a * n * r.2.1) r.1 y.1, r.2.1 * (b * y.2),
r.2.2.1 * b + a * r.2.2.2, r.2.2.2 * b)
/-- The check of one condition of `prop:rsc-cert` for `P = M / F`: indices `< n`, denominators `> 0`, weight sum
`≥ 1`, and `M/F - ∑ (aₖ/bₖ) Y[kₖ] ∈ 𝒦_pos` (cleared of the positive denominator `F · T`). -/
def dom (n : ℕ) (Yc : List (List IPt)) (P : IPt) (comb : List (ℕ × ℕ × ℕ)) : Bool :=
comb.all (fun e => decide (e.1 < n) && decide (0 < e.2.2)) &&
(let r := combI Yc comb
decide (r.2.2.2 ≤ r.2.2.1) &&
inK (List.zipWith (fun m v => (m * r.2.1 : ℤ) - (P.2 * v : ℤ)) P.1 r.1))
/-- One stage block: for each `x` in `xs` and each `z` in `Zs`, `x ∘ z` dominates the given
combination of `Y` (of size `n`, chunked as `Yc`). -/
def checkBlock (n : ℕ) (Yc : List (List IPt)) (Zs : List IPt) (xs : List IPt)
(combos : List (List (List (ℕ × ℕ × ℕ)))) : Bool :=
xs.length == combos.length &&
(xs.zip combos).all (fun xc => xc.2.length == Zs.length &&
(Zs.zip xc.2).all (fun zc => dom n Yc (mergeI xc.1 zc.1) zc.2))
/-! ### Decoding the flat data -/
/-- Read `c` weight entries `(k, a, b)`. -/
def takeComb : ℕ → List ℕ → List (ℕ × ℕ × ℕ) × List ℕ
| 0, l => ([], l)
| c + 1, k :: a :: b :: l =>
let r := takeComb c l
((k, a, b) :: r.1, r.2)
| _ + 1, _ => ([], [])
/-- Read `m` combinations, each given as its length followed by its entries. -/
def decodeCombs : ℕ → List ℕ → List (List (ℕ × ℕ × ℕ))
| 0, _ => []
| _ + 1, [] => []
| m + 1, c :: l =>
let r := takeComb c l
r.1 :: decodeCombs m r.2
/-- Read a point: eight numerators followed by the common denominator. -/
def decodePt : List ℕ → IPt
| [a0, a1, a2, a3, a4, a5, a6, a7, d] => ([a0, a1, a2, a3, a4, a5, a6, a7], d)
| _ => zeroI
/-- Read a leaf entry: `ν, c₂, c₃`, then one combination. -/
def decodeLeaf : List ℕ → (ℕ × ℕ × ℕ) × List (ℕ × ℕ × ℕ)
| ν :: c₂ :: c₃ :: c :: l => ((ν, c₂, c₃), (takeComb c l).1)
| _ => ((0, 0, 0), [])
/-- Read a chain of length one: `ν, c₂, c₃`, then `n` combinations. -/
def decodeChain1 (n : ℕ) : List ℕ → (ℕ × ℕ × ℕ) × List (List (ℕ × ℕ × ℕ))
| ν :: c₂ :: c₃ :: l => ((ν, c₂, c₃), decodeCombs n l)
| _ => ((0, 0, 0), [])
/-! ### Family checkers -/
def okPt (P : IPt) : Bool := P.1.length == 8 && decide (0 < P.2)
def okPts (Y : List IPt) : Bool := Y.all okPt
/-- `2000 · D · fin~(N / D)`, with `fin~ = A + C₂ + O₀₀/2 + O₀₁ + O₁ + q₂ O₂`. -/
def finN : List ℕ → ℕ
| [N0, _, _, N3, N4, N5, N6, N7] =>
2000 * N0 + 2000 * N3 + 1000 * N4 + 2000 * N5 + 2000 * N6 + 1860 * N7
| _ => 0
/-- Strict lexicographic order of the values `N / D`, `N' / D'` (cross-multiplied). -/
def ltLex (D D' : ℕ) : List ℕ → List ℕ → Bool
| a :: as, b :: bs => decide (a * D' < b * D) || (decide (a * D' = b * D) && ltLex D D' as bs)
| _, _ => false
def sortedZ : List IPt → Bool
| P :: Q :: rest => ltLex P.2 Q.2 P.1 Q.1 && sortedZ (Q :: rest)
| _ => true
/-- The facts about `Z` itself: `1024` well-formed points in strictly increasing lexicographic
order, each with `fin~ > 0.6060`. -/
def checkZ (Z : List IPt) : Bool :=
Z.length == 1024 && okPts Z && sortedZ Z &&
Z.all (fun z => decide (6060 * 2000 * z.2 < 10000 * finN z.1))
/-- (C2): `ê^{-1-ν} Init(ν)` for `ν ≤ 24` (entries `0, …, 24`) and `ê^{-26} Init(∞)` (entry `25`). -/
def checkC2 (n : ℕ) (Yc : List (List IPt)) (combos : List (List (ℕ × ℕ × ℕ))) : Bool :=
combos.length == 26 &&
((List.range 25).zip combos).all (fun e => dom n Yc (initI e.1 0 0) e.2) &&
dom n Yc initInfI (combos.getD 25 [])
/-- Leaf entries `((ν, c₂, c₃), comb)`: `ê^{-1-ν} Init~(ν; c₂, c₃)` dominates `comb`. -/
def checkLeaves (n : ℕ) (Yc : List (List IPt)) (entries : List ((ℕ × ℕ × ℕ) × List (ℕ × ℕ × ℕ))) :
Bool :=
entries.all (fun e => dom n Yc (initI e.1.1 e.1.2.1 e.1.2.2) e.2)
/-- Chains of length one `((ν, c₂, c₃), combos)`: `ê^{-1-ν} Init~(ν; c₂, c₃) ∘̃ z` dominates the
given combination of `Z` for every `z ∈ Z`. -/
def checkChain1 (n : ℕ) (Yc : List (List IPt)) (Zs : List IPt)
(entries : List ((ℕ × ℕ × ℕ) × List (List (ℕ × ℕ × ℕ)))) : Bool :=
entries.all (fun e => checkBlock n Yc Zs [initI e.1.1 e.1.2.1 e.1.2.2] [e.2])
/-- `u = q₂^{c₂} q₃^{c₃}` and `w = ϖ₂^{c₂} ϖ₃^{c₃}` as numerator/denominator pairs. -/
def uF (c₂ c₃ : ℕ) : ℕ × ℕ := (93 ^ c₂ * 923 ^ c₃, 100 ^ c₂ * 1000 ^ c₃)
def wF (c₂ c₃ : ℕ) : ℕ × ℕ := (272657 ^ c₂ * 288677 ^ c₃, 250000 ^ (c₂ + c₃))
/-- The target chain length `j` of (C5) at `(ν, c₂, c₃)`, from the paper's `d_min`. -/
def jTarget (ν c₂ : ℕ) : ℕ := if c₂ = 0 then RSCCert.jOf RSCParams.d₃ ν else RSCCert.jOf RSCParams.d₂ ν
/-- The lattice of (C5): `1 ≤ ν ≤ 36`, `1 ≤ c₂ + c₃ ≤ ν`, in a fixed order. -/
def lattice5 : List (ℕ × ℕ × ℕ) :=
(List.range 36).flatMap fun i =>
(List.range (i + 2)).flatMap fun c₂ =>
((List.range (i + 2 - c₂)).filter (fun c₃ => decide (1 ≤ c₂ + c₃))).map fun c₃ => (i + 1, c₂, c₃)
/-- The lattice of (C4): `4 ≤ ν ≤ 36` (exactly the `2 ≤ ν ≤ 36` with `d₃ ν ≤ 1`) and
`1 ≤ c₂ + c₃ ≤ ν - 1`. -/
def lattice4 : List (ℕ × ℕ × ℕ) :=
(List.range 33).flatMap fun i =>
(List.range (i + 4)).flatMap fun c₂ =>
((List.range (i + 4 - c₂)).filter (fun c₃ => decide (1 ≤ c₂ + c₃))).map fun c₃ => (i + 4, c₂, c₃)
/-- Read `m` combination components `(kind, idx, a, b)` with `λ = a / b`. -/
def takeComp : ℕ → List ℕ → List (ℕ × ℕ × ℕ × ℕ)
| 0, _ => []
| m + 1, k :: i :: a :: b :: l => (k, i, a, b) :: takeComp m l
| _ + 1, _ => []
/-- A convex-combination witness, components `((c₂', c₃'), a, b)` with `λ = a / b`:
`b > 0`, `∑ λ = 1`, `∑ λ u' = u`, `∑ λ w' = w`, all exactly. -/
def combWitness (c₂ c₃ : ℕ) (comps : List ((ℕ × ℕ) × ℕ × ℕ)) : Bool :=
comps.all (fun e => decide (0 < e.2.2)) &&
(let S := comps.foldr (fun e r => (r.1 * e.2.2 + e.2.1 * r.2, r.2 * e.2.2)) (0, 1)
decide (S.1 = S.2)) &&
(let u := uF c₂ c₃
let S := comps.foldr (fun e r =>
let uk := uF e.1.1 e.1.2
(r.1 * (e.2.2 * uk.2) + e.2.1 * uk.1 * r.2, r.2 * (e.2.2 * uk.2))) (0, 1)
decide (S.1 * u.2 = u.1 * S.2)) &&
(let w := wF c₂ c₃
let S := comps.foldr (fun e r =>
let wk := wF e.1.1 e.1.2
(r.1 * (e.2.2 * wk.2) + e.2.1 * wk.1 * r.2, r.2 * (e.2.2 * wk.2))) (0, 1)
decide (S.1 * w.2 = w.1 * S.2))
/-- The exposure counts of component `e`: kind `0` is `(0, 0)`, otherwise entry `idx` of `T`. -/
def compPt {α : Type} (T : List ((ℕ × ℕ × ℕ) × α)) (d : α) (e : ℕ × ℕ × ℕ × ℕ) : ℕ × ℕ :=
if e.1 = 0 then (0, 0) else ((T.getD e.2.1 ((0, 0, 0), d)).1.2.1, (T.getD e.2.1 ((0, 0, 0), d)).1.2.2)
/-- (C5) lattice check against the table `T` of certified chains (entries `((ν, c₂, c₃), j)`).
Per lattice point the data is `[0, k]` (entry `k` of `T` is this point, with `j ≤ jTarget`) or
`[1, m, kind₁, idx₁, a₁, b₁, …]` (a convex combination of `(0, 0)` (kind `0`) and entries of `T`
(kind `1`) at the same `ν` with `j ≤ jTarget`). -/
def latOK5 (T : List ((ℕ × ℕ × ℕ) × ℕ)) (pt : ℕ × ℕ × ℕ) (dat : List ℕ) : Bool :=
match dat with
| [0, k] => decide (k < T.length) && decide ((T.getD k ((0, 0, 0), 0)).1 = pt) &&
decide ((T.getD k ((0, 0, 0), 0)).2 ≤ jTarget pt.1 pt.2.1)
| 1 :: m :: rest =>
let comps := takeComp m rest
comps.all (fun e => decide (e.1 = 0) ||
(decide (e.1 = 1) && decide (e.2.1 < T.length) &&
decide ((T.getD e.2.1 ((0, 0, 0), 0)).1.1 = pt.1) &&
decide ((T.getD e.2.1 ((0, 0, 0), 0)).2 ≤ jTarget pt.1 pt.2.1))) &&
combWitness pt.2.1 pt.2.2 (comps.map fun e => (compPt T 0 e, e.2.2.1, e.2.2.2))
| _ => false
def checkLattice5 (T : List ((ℕ × ℕ × ℕ) × ℕ)) (wit : List (List ℕ)) : Bool :=
lattice5.length == wit.length && (lattice5.zip wit).all (fun e => latOK5 T e.1 e.2)
/-- (C4) lattice check against the table `T` of certified leaves (entries `((ν, c₂, c₃), ())`),
in the same data format; components are `(0, 0)` or leaves at the same `ν`. -/
def latOK4 (T : List ((ℕ × ℕ × ℕ) × Unit)) (pt : ℕ × ℕ × ℕ) (dat : List ℕ) : Bool :=
match dat with
| [0, k] => decide (k < T.length) && decide ((T.getD k ((0, 0, 0), ())).1 = pt)
| 1 :: m :: rest =>
let comps := takeComp m rest
comps.all (fun e => decide (e.1 = 0) ||
(decide (e.1 = 1) && decide (e.2.1 < T.length) &&
decide ((T.getD e.2.1 ((0, 0, 0), ())).1.1 = pt.1))) &&
combWitness pt.2.1 pt.2.2 (comps.map fun e => (compPt T () e, e.2.2.1, e.2.2.2))
| _ => false
def checkLattice4 (T : List ((ℕ × ℕ × ℕ) × Unit)) (wit : List (List ℕ)) : Bool :=
lattice4.length == wit.length && (lattice4.zip wit).all (fun e => latOK4 T e.1 e.2)
/-! ### Real-valued semantics -/
open MaxLeafFormal.RSCCert MaxLeafFormal.RSCParams
open MaxLeafFormal.Antinorm8 (Kpos PZ initInf)
open Pointwise
noncomputable section
/-- The value `N / D` of a point. -/
def val (P : IPt) : Fin 8 → ℝ := fun s => ((P.1.getD s 0 : ℕ) : ℝ) / (P.2 : ℝ)
/-- The finite set of values of a list of points. -/
def finsetOf (Y : List IPt) : Finset (Fin 8 → ℝ) :=
open Classical in (Y.map val).toFinset
/-- `x ∘̃ z ∈ conv(Y') + 𝒦_pos` for all `x ∈ X`, `z ∈ Z` (one stage of a chain). -/
def StageFact (Z X Y' : List IPt) : Prop :=
∀ x ∈ X, ∀ z ∈ Z, merge p₂ p₃ (val x) (val z) ∈ convexHull ℝ (finsetOf Y' : Set (Fin 8 → ℝ)) + Kpos
/-- (C5) for one exposure point with chains of length `j`. -/
def ChainFact (Z : List IPt) (e : (ℕ × ℕ × ℕ) × ℕ) : Prop :=
∀ Qs : List (Fin 8 → ℝ), Qs.length = e.2 → (∀ Q ∈ Qs, Q ∈ PZ (finsetOf Z) ∧ 0 ≤ Q) →
Qs.foldl (merge p₂ p₃) ((ê ^ (1 + e.1.1))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ e.1.1 e.1.2.1 e.1.2.2)
∈ PZ (finsetOf Z)
/-- (C4) for one leaf exposure point. -/
def LeafFact (Z : List IPt) (e : (ℕ × ℕ × ℕ) × Unit) : Prop :=
init p₂ p₃ y ϖ₂ ϖ₃ e.1.1 e.1.2.1 e.1.2.2 ∈ ê ^ (1 + e.1.1) • PZ (finsetOf Z)
/-! ### Soundness -/
theorem val_nonneg (P : IPt) : 0 ≤ val P := fun _ => div_nonneg (Nat.cast_nonneg _) (Nat.cast_nonneg _)
theorem okPt_parts_aux {P : IPt} (h : okPt P = true) :
∃ a0 a1 a2 a3 a4 a5 a6 a7 D : ℕ, P = ([a0, a1, a2, a3, a4, a5, a6, a7], D) ∧ 0 < D := by
obtain ⟨N, D⟩ := P
unfold okPt at h
simp only [Bool.and_eq_true, beq_iff_eq, decide_eq_true_eq] at h
obtain ⟨hl, hD⟩ := h
rcases N with _ | ⟨a0, _ | ⟨a1, _ | ⟨a2, _ | ⟨a3, _ | ⟨a4, _ | ⟨a5, _ | ⟨a6, _ | ⟨a7, _ | ⟨a8, N⟩⟩⟩⟩⟩⟩⟩⟩⟩
all_goals first
| exact ⟨_, _, _, _, _, _, _, _, D, rfl, hD⟩
| (simp only [List.length_cons, List.length_nil] at hl; omega)
theorem ehat_eq : ê = (eN : ℝ) / (eD : ℝ) := by
unfold ê eN eD; norm_num
theorem val_mergeI {P Q : IPt} (hP : okPt P = true) (hQ : okPt Q = true) :
val (mergeI P Q) = merge p₂ p₃ (val P) (val Q) := by
obtain ⟨a0, a1, a2, a3, a4, a5, a6, a7, D, rfl, hD⟩ := okPt_parts_aux hP
obtain ⟨b0, b1, b2, b3, b4, b5, b6, b7, E, rfl, hE⟩ := okPt_parts_aux hQ
have hD' : (D : ℝ) ≠ 0 := Nat.cast_ne_zero.2 hD.ne'
have hE' : (E : ℝ) ≠ 0 := Nat.cast_ne_zero.2 hE.ne'
funext s
fin_cases s <;>
simp [val, mergeI, mergeN, MaxLeafFormal.RSCCert.merge, MaxLeafFormal.RSCCert.chiS,
MaxLeafFormal.Antinorm8.chiCu, MaxLeafFormal.Antinorm8.chiCs, MaxLeafFormal.Antinorm8.chiOs,
MaxLeafFormal.Antinorm8.chiOx, MaxLeafFormal.Antinorm8.chiOu, p₂, p₃] <;>
push_cast <;> field_simp <;> ring
theorem okPt_mergeI {P Q : IPt} (hP : okPt P = true) (hQ : okPt Q = true) :
okPt (mergeI P Q) = true := by
obtain ⟨a0, a1, a2, a3, a4, a5, a6, a7, D, rfl, hD⟩ := okPt_parts_aux hP
obtain ⟨b0, b1, b2, b3, b4, b5, b6, b7, E, rfl, hE⟩ := okPt_parts_aux hQ
have hpos : 0 < 1000 * D * E := Nat.mul_pos (Nat.mul_pos (by norm_num) hD) hE
simp [okPt, mergeI, mergeN, hpos]
theorem val_initI (ν c₂ c₃ : ℕ) :
val (initI ν c₂ c₃) = (ê ^ (1 + ν))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ ν c₂ c₃ := by
rw [ehat_eq]
funext s
fin_cases s <;>
norm_num [val, initI, init, eN, eD, p₂, p₃, y, ϖ₂, ϖ₃, div_pow, inv_pow, mul_pow] <;>
field_simp <;> ring
theorem okPt_initI (ν c₂ c₃ : ℕ) : okPt (initI ν c₂ c₃) = true := by
have hD : 0 < eN ^ (1 + ν) * 200 * (100 ^ c₂ * 1000 ^ c₃) * (2 ^ ν * 250000 ^ (c₂ + c₃)) := by
unfold eN; positivity
simpa [okPt, initI] using hD
theorem val_initInfI : val initInfI = (ê ^ (ν₀ + 2))⁻¹ • initInf p₂ y := by
rw [ehat_eq]
funext s
fin_cases s <;>
norm_num [val, initInfI, initInf, eN, eD, ν₀, p₂, y, div_pow, inv_pow, mul_pow] <;>
field_simp <;> ring
theorem okPt_initInfI : okPt initInfI = true := by
have hD : 0 < eN ^ 26 * 200 := by unfold eN; positivity
simpa [okPt, initInfI] using hD
/-- Peeling construction: a point with `P 0 ≥ 0` and the `e₃`-coefficient nonnegative is in `Kpos`. -/
theorem kpos_of_peel (P : Fin 8 → ℝ) (h0 : 0 ≤ P 0)
(h3 : 0 ≤ P 3 + min 0 (cgS2 P) + min 0 (cgS5 P)) : P ∈ Kpos := by
have kA : ∀ x : ℝ, max 0 x - max 0 (-x) = x := by
intro x
rcases le_total 0 x with h | h
· rw [max_eq_right h, max_eq_left (by linarith)]; ring
· rw [max_eq_left h, max_eq_right (by linarith)]; ring
have kB : ∀ x : ℝ, min 0 x + max 0 (-x) = 0 := by
intro x
rcases le_total 0 x with h | h
· rw [min_eq_left h, max_eq_left (by linarith)]; ring
· rw [min_eq_right h, max_eq_right (by linarith)]; ring
have hS2 : cgS2 P = P 2 + min 0 (P 1) := rfl
have hS6 : cgS6 P = P 6 + min 0 (P 7) := rfl
have hS5 : cgS5 P = P 5 + min 0 (P 4) + min 0 (cgS6 P) := rfl
refine Kpos_of_gen P ⟨![P 0, max 0 (P 1), max 0 (cgS2 P), P 3 + min 0 (cgS2 P) + min 0 (cgS5 P),
max 0 (P 4), max 0 (cgS5 P), max 0 (cgS6 P), max 0 (P 7), max 0 (-cgS2 P), max 0 (-P 1),
max 0 (-cgS5 P), max 0 (-P 4), max 0 (-cgS6 P), max 0 (-P 7)], ?_, ?_⟩
· intro i
fin_cases i <;> first | exact h0 | exact le_max_left _ _ | exact h3
· funext k
fin_cases k <;> simp [Fin.sum_univ_succ, gen, unitVec] <;>
linarith [kA (cgS2 P), kA (P 1), kA (P 4), kA (cgS5 P), kA (cgS6 P), kA (P 7),
kB (cgS2 P), kB (P 1), kB (cgS5 P), kB (P 4), kB (cgS6 P), kB (P 7), hS2, hS5, hS6]
theorem inK_sound {v : List ℤ} (h : inK v = true) :
(fun s : Fin 8 => ((v.getD s 0 : ℤ) : ℝ)) ∈ Kpos := by
rcases v with _ | ⟨d0, _ | ⟨d1, _ | ⟨d2, _ | ⟨d3, _ | ⟨d4, _ | ⟨d5, _ | ⟨d6, _ | ⟨d7, _ | ⟨d8, vs⟩⟩⟩⟩⟩⟩⟩⟩⟩
all_goals try (simp [inK] at h; done)
case cons.cons.cons.cons.cons.cons.cons.cons.nil =>
simp only [inK, Bool.and_eq_true, decide_eq_true_eq] at h
obtain ⟨h0, h3⟩ := h
apply kpos_of_peel
· show (0:ℝ) ≤ (d0:ℝ)
exact_mod_cast h0
· show (0:ℝ) ≤ (d3:ℝ) + min 0 ((d2:ℝ) + min 0 (d1:ℝ))
+ min 0 ((d5:ℝ) + min 0 (d4:ℝ) + min 0 ((d6:ℝ) + min 0 (d7:ℝ)))
exact_mod_cast h3
theorem getPt_chunksAux_aux (n : ℕ) : ∀ (l : List IPt), l.length ≤ n →
∀ k (hk : k < l.length), getPt (chunksAux n l) k = l[k] := by
induction n with
| zero => intro l hl k hk; omega
| succ n ih =>
intro l hl k hk
match l, hl, hk with
| [], _, hk => simp at hk
| x :: xs, hl, hk =>
simp only [chunksAux]
unfold getPt
by_cases hk32 : k < 32
· have h1 : k / 32 = 0 := by omega
have h2 : k % 32 = k := by omega
rw [h1, h2, List.getD_cons_zero]
rw [List.getD_eq_getElem]
· exact List.getElem_take
· simp only [List.length_take, List.length_cons] at hk ⊢
omega
· have h1 : k / 32 = (k - 32) / 32 + 1 := by omega
have h2 : k % 32 = (k - 32) % 32 := by omega
rw [h1, h2, List.getD_cons_succ]
have key := ih (List.drop 32 (x :: xs)) (by simp only [List.length_drop, List.length_cons] at hl ⊢; omega)
(k - 32) (by simp only [List.length_drop, List.length_cons] at hk ⊢; omega)
unfold getPt at key
rw [key]
simp only [List.getElem_drop]
congr 1
omega
theorem getPt_chunks32 (Y : List IPt) (k : ℕ) (hk : k < Y.length) :
getPt (chunks32 Y) k = Y[k] := by
unfold chunks32
exact getPt_chunksAux_aux Y.length Y le_rfl k hk
theorem dom_aux_okdims {P : IPt} (h : okPt P = true) : P.1.length = 8 ∧ 0 < P.2 := by
unfold okPt at h
simpa only [Bool.and_eq_true, beq_iff_eq, decide_eq_true_eq] using h
theorem dom_aux_getD {α β γ : Type} (f : β → γ → α) (d : α) (d1 : β) (d2 : γ) (l : List β)
(l' : List γ) (hl : l.length = 8) (hl' : l'.length = 8) (s : ℕ) (hs : s < 8) :
(List.zipWith f l l').getD s d = f (l.getD s d1) (l'.getD s d2) := by
have h1 : s < l.length := by omega
have h2 : s < l'.length := by omega
have h3 : s < (List.zipWith f l l').length := by
rw [List.length_zipWith, hl, hl']; omega
rw [List.getD_eq_getElem _ _ h3, List.getD_eq_getElem _ _ h1, List.getD_eq_getElem _ _ h2,
List.getElem_zipWith]
theorem dom_aux_coe (l : List ℕ) :
(do let a ← l; pure (a : ℤ) : List ℤ) = l.map (fun a : ℕ => (a : ℤ)) := by
induction l with
| nil => rfl
| cons x xs ih => rw [List.map_cons, ← ih]; rfl
theorem dom_aux_map_getD (l : List ℕ) (s : ℕ) (hs : s < l.length) :
(l.map (fun a : ℕ => (a : ℤ))).getD s 0 = ((l.getD s 0 : ℕ) : ℤ) := by
rw [List.getD_eq_getElem _ _ (show s < (l.map (fun a : ℕ => (a : ℤ))).length by simpa using hs),
List.getD_eq_getElem _ _ hs, List.getElem_map]
theorem dom_aux_spec (Yc : List (List IPt)) : ∀ comb : List (ℕ × ℕ × ℕ),
(∀ e ∈ comb, 0 < e.2.2 ∧ okPt (getPt Yc e.1) = true) →
0 < (combI Yc comb).2.1 ∧ 0 < (combI Yc comb).2.2.2 ∧ (combI Yc comb).1.length = 8 ∧
(fun s : Fin 8 => (((combI Yc comb).1.getD s 0 : ℕ) : ℝ) / ((combI Yc comb).2.1 : ℝ)) =
(comb.map fun e => ((e.2.1 : ℝ) / e.2.2) • val (getPt Yc e.1)).sum ∧
(((combI Yc comb).2.2.1 : ℝ) / ((combI Yc comb).2.2.2 : ℝ)) =
(comb.map fun e => (e.2.1 : ℝ) / e.2.2).sum := by
intro comb
induction comb with
| nil =>
intro _
refine ⟨by simp [combI], by simp [combI], by simp [combI], ?_, by simp [combI]⟩
funext s
fin_cases s <;> simp [combI]
| cons e cs ih =>
obtain ⟨k, a, b⟩ := e
intro h
have hb : 0 < b := by
have := (h (k, a, b) (by simp)).1
simpa using this
have hy : okPt (getPt Yc k) = true := (h (k, a, b) (by simp)).2
obtain ⟨hT', ht', hl', hV', hs'⟩ := ih (fun e he => h e (by simp [he]))
obtain ⟨hyl, hyp⟩ := dom_aux_okdims hy
simp only [combI]
generalize combI Yc cs = r at hT' ht' hl' hV' hs' ⊢
have hT0 : (r.2.1 : ℝ) ≠ 0 := by exact_mod_cast hT'.ne'
have hb0 : (b : ℝ) ≠ 0 := by exact_mod_cast hb.ne'
have hy0 : ((getPt Yc k).2 : ℝ) ≠ 0 := by exact_mod_cast hyp.ne'
have ht0 : (r.2.2.2 : ℝ) ≠ 0 := by exact_mod_cast ht'.ne'
refine ⟨Nat.mul_pos hT' (Nat.mul_pos hb hyp), Nat.mul_pos ht' hb, ?_, ?_, ?_⟩
· rw [List.length_zipWith, hl', hyl, min_self]
· funext s
rw [dom_aux_getD _ _ 0 0 _ _ hl' hyl s.1 s.isLt]
have hVs := congrFun hV' s
simp only [List.map_cons, List.sum_cons, Pi.add_apply, Pi.smul_apply, smul_eq_mul, val] at hVs ⊢
rw [← hVs]
push_cast
field_simp
ring
· simp only [List.map_cons, List.sum_cons]
rw [← hs']
push_cast
field_simp
ring
theorem dom_aux_conv {α : Type} (C : Set (Fin 8 → ℝ)) (hC : Convex ℝ C) (x0 : Fin 8 → ℝ)
(hx0 : x0 ∈ C) (f : α → ℝ) (g : α → Fin 8 → ℝ) (L : List α)
(hL : ∀ a ∈ L, 0 ≤ f a ∧ g a ∈ C) :
∃ c ∈ C, (L.map fun a => f a • g a).sum = (L.map f).sum • c := by
induction L with
| nil => exact ⟨x0, hx0, by simp⟩
| cons a L ih =>
obtain ⟨c', hc', hsum⟩ := ih (fun b hb => hL b (List.mem_cons_of_mem _ hb))
obtain ⟨ha, hga⟩ := hL a (List.mem_cons_self ..)
have hμ : 0 ≤ (L.map f).sum := List.sum_nonneg (fun x hx => by
obtain ⟨b, hb, rfl⟩ := List.mem_map.mp hx
exact (hL b (List.mem_cons_of_mem _ hb)).1)
by_cases hz : f a + (L.map f).sum = 0
· have h1 : f a = 0 := by linarith
have h2 : (L.map f).sum = 0 := by linarith
refine ⟨x0, hx0, ?_⟩
simp only [List.map_cons, List.sum_cons]
rw [hsum]
simp [h1, h2]
· have hw : 0 < f a + (L.map f).sum := lt_of_le_of_ne (add_nonneg ha hμ) (Ne.symm hz)
have hw' : f a + (L.map f).sum ≠ 0 := hw.ne'
refine ⟨(f a / (f a + (L.map f).sum)) • g a +
((L.map f).sum / (f a + (L.map f).sum)) • c', ?_, ?_⟩
· exact hC hga hc' (div_nonneg ha hw.le) (div_nonneg hμ hw.le)
(by rw [← add_div, div_self hw'])
· have e1 : (f a + (L.map f).sum) * (f a / (f a + (L.map f).sum)) = f a := by
field_simp
have e2 : (f a + (L.map f).sum) * ((L.map f).sum / (f a + (L.map f).sum)) =
(L.map f).sum := by
field_simp
simp only [List.map_cons, List.sum_cons]
rw [hsum, smul_add, smul_smul, smul_smul, e1, e2]
theorem dom_aux_val_mem (Y : List IPt) (k : ℕ) (hk : k < Y.length) :
val (getPt (chunks32 Y) k) ∈ convexHull ℝ (finsetOf Y : Set (Fin 8 → ℝ)) := by
rw [getPt_chunks32 Y k hk]
have hm : val (Y[k]) ∈ finsetOf Y := by
unfold finsetOf
exact List.mem_toFinset.mpr (List.mem_map_of_mem (List.getElem_mem ..))
exact subset_convexHull ℝ _ (Finset.mem_coe.mpr hm)
theorem dom_aux_nonneg (Y : List IPt) : ∀ y ∈ finsetOf Y, 0 ≤ y := by
intro y hy
unfold finsetOf at hy
obtain ⟨p, _, rfl⟩ := List.mem_map.mp (List.mem_toFinset.mp hy)
exact val_nonneg p
/-- The domination check is sound: `P ∈ conv(Y) + 𝒦_pos`. -/
theorem dom_sound {Y : List IPt} (hY : okPts Y = true) {P : IPt} (hP : okPt P = true)
{comb : List (ℕ × ℕ × ℕ)} (h : dom Y.length (chunks32 Y) P comb = true) :
val P ∈ convexHull ℝ (finsetOf Y : Set (Fin 8 → ℝ)) + Kpos := by
have hne : ∃ e, e ∈ comb := by
cases comb with
| nil => simp [dom, combI] at h
| cons e cs => exact ⟨e, by simp⟩
have hY' : Y.all okPt = true := hY
have hcomb : ∀ e ∈ comb, e.1 < Y.length ∧ 0 < e.2.2 := by
intro e he
have h1 := h
unfold dom at h1
rw [Bool.and_eq_true] at h1
have h2 := List.all_eq_true.mp h1.1 e he
simpa using h2
have hrest := h
unfold dom at hrest
rw [Bool.and_eq_true] at hrest
obtain ⟨-, hK⟩ := hrest
simp only [Bool.and_eq_true, decide_eq_true_eq] at hK
obtain ⟨hle, hKin⟩ := hK
have hpts : ∀ e ∈ comb, okPt (getPt (chunks32 Y) e.1) = true := by
intro e he
have hk := (hcomb e he).1
rw [getPt_chunks32 Y _ hk]
exact List.all_eq_true.mp hY' _ (List.getElem_mem ..)
obtain ⟨hT, ht, hVl, hV, hst⟩ :=
dom_aux_spec (chunks32 Y) comb (fun e he => ⟨(hcomb e he).2, hpts e he⟩)
obtain ⟨hPl, hPpos⟩ := dom_aux_okdims hP
set r := combI (chunks32 Y) comb with hr
have hD0 : (P.2 : ℝ) ≠ 0 := by exact_mod_cast hPpos.ne'
have hT0 : (r.2.1 : ℝ) ≠ 0 := by exact_mod_cast hT.ne'
have ht' : (0 : ℝ) < (r.2.2.2 : ℝ) := by exact_mod_cast ht
have hKW : (fun s : Fin 8 => ((P.1.getD s 0 : ℕ) : ℝ) * (r.2.1 : ℝ) -
(P.2 : ℝ) * ((r.1.getD s 0 : ℕ) : ℝ)) ∈ Kpos := by
rw [dom_aux_coe, dom_aux_coe] at hKin
have hA : (P.1.map (fun a : ℕ => (a : ℤ))).length = 8 := by simp [hPl]
have hB : (r.1.map (fun a : ℕ => (a : ℤ))).length = 8 := by simp [hVl]
convert MaxLeafFormal.RSCCheck.inK_sound hKin using 1
funext s
have hsP : s.1 < P.1.length := by omega
have hsV : s.1 < r.1.length := by omega
rw [dom_aux_getD _ _ 0 0 _ _ hA hB s.1 s.isLt, dom_aux_map_getD _ _ hsP,
dom_aux_map_getD _ _ hsV]
push_cast
ring
have hV' : ∀ s : Fin 8, ((r.1.getD s 0 : ℕ) : ℝ) / (r.2.1 : ℝ) = (comb.map fun e =>
((e.2.1 : ℝ) / e.2.2) • val (getPt (chunks32 Y) e.1)).sum s := fun s => congrFun hV s
obtain ⟨x0, hx0⟩ : ∃ x0, x0 ∈ convexHull ℝ (finsetOf Y : Set (Fin 8 → ℝ)) := by
obtain ⟨e, he⟩ := hne
exact ⟨_, dom_aux_val_mem Y _ (hcomb e he).1⟩
obtain ⟨c, hcC, hcS⟩ := dom_aux_conv (convexHull ℝ (finsetOf Y : Set (Fin 8 → ℝ)))
(convex_convexHull ℝ _) _ hx0 (fun e : ℕ × ℕ × ℕ => (e.2.1 : ℝ) / e.2.2)
(fun e => val (getPt (chunks32 Y) e.1)) comb
(fun e he => ⟨div_nonneg (Nat.cast_nonneg _) (Nat.cast_nonneg _),
dom_aux_val_mem Y _ (hcomb e he).1⟩)
have hσ : 1 ≤ (comb.map fun e => (e.2.1 : ℝ) / e.2.2).sum := by
rw [← hst]
exact (one_le_div ht').mpr (by exact_mod_cast hle)
have hc0 : 0 ≤ c := MaxLeafFormal.Antinorm8.convexHull_nonneg (dom_aux_nonneg Y) hcC
set σ := (comb.map fun e => (e.2.1 : ℝ) / e.2.2).sum with hσdef
set S := (comb.map fun e => ((e.2.1 : ℝ) / e.2.2) • val (getPt (chunks32 Y) e.1)).sum
with hSdef
have hVs : ∀ s : Fin 8, ((r.1.getD s 0 : ℕ) : ℝ) / (r.2.1 : ℝ) = S s := hV'
have hDiff : val P - S ∈ Kpos := by
have hEq : val P - S = (1 / ((P.2 : ℝ) * (r.2.1 : ℝ))) •
(fun s : Fin 8 => ((P.1.getD s 0 : ℕ) : ℝ) * (r.2.1 : ℝ) -
(P.2 : ℝ) * ((r.1.getD s 0 : ℕ) : ℝ)) := by
funext s
have := hVs s
simp only [Pi.sub_apply, Pi.smul_apply, smul_eq_mul, val]
rw [← this]
field_simp
rw [hEq]
exact MaxLeafFormal.Antinorm8.Kpos_smul (by positivity) hKW
have hSc : S - c = (σ - 1) • c := by
rw [hcS, sub_smul, one_smul]
have hSK : S - c ∈ Kpos := by
rw [hSc]
apply MaxLeafFormal.Antinorm8.Kpos_of_nonneg
rw [Pi.le_def]
intro s
simp only [Pi.zero_apply, Pi.smul_apply, smul_eq_mul]
exact mul_nonneg (by linarith) (hc0 s)
have key : val P = c + ((val P - S) + (S - c)) := by abel
rw [key]
exact Set.add_mem_add hcC (MaxLeafFormal.Antinorm8.Kpos_add hDiff hSK)
theorem checkBlock_sound {Y Zs xs : List IPt} (hY : okPts Y = true) (hZs : okPts Zs = true)
(hxs : okPts xs = true) {combos : List (List (List (ℕ × ℕ × ℕ)))}
(h : checkBlock Y.length (chunks32 Y) Zs xs combos = true) : StageFact Zs xs Y := by
unfold StageFact
unfold checkBlock at h
simp only [Bool.and_eq_true, beq_iff_eq, List.all_eq_true] at h
obtain ⟨hlen, hall⟩ := h
have hxs' : xs.all okPt = true := hxs
have hZs' : Zs.all okPt = true := hZs
intro x hx z hz
obtain ⟨i, hi, rfl⟩ := List.mem_iff_getElem.mp hx
obtain ⟨j, hj, rfl⟩ := List.mem_iff_getElem.mp hz
have hic : i < combos.length := by omega
have hm1 : (xs[i], combos[i]) ∈ xs.zip combos :=
List.mem_iff_getElem.mpr ⟨i, by rw [List.length_zip]; omega, by simp⟩
obtain ⟨hcl, hall2⟩ := hall _ hm1
have hcl' : combos[i].length = Zs.length := hcl
have hm2 : (Zs[j], combos[i][j]) ∈ Zs.zip combos[i] :=
List.mem_iff_getElem.mpr ⟨j, by rw [List.length_zip]; omega, by simp⟩
have hd := hall2 _ hm2
have hxok : okPt xs[i] = true := List.all_eq_true.mp hxs' _ (List.getElem_mem ..)
have hzok : okPt Zs[j] = true := List.all_eq_true.mp hZs' _ (List.getElem_mem ..)
have hd' := dom_sound hY (okPt_mergeI hxok hzok) hd
rw [val_mergeI hxok hzok] at hd'
exact hd'
theorem okPts_of_subset {Y X : List IPt} (hY : okPts Y = true) (hX : ∀ x ∈ X, x ∈ Y) :
okPts X = true := by
simp only [okPts, List.all_eq_true] at hY ⊢
exact fun x hx => hY x (hX x hx)
/-- The value vector of a point, as a list of real numbers. -/
def vlist (P : IPt) : List ℝ := P.1.map (fun (a : ℕ) => (a : ℝ) / (P.2 : ℝ))
theorem okPt_pos {P : IPt} (h : okPt P = true) : 0 < P.2 := by
simp only [okPt, Bool.and_eq_true, decide_eq_true_eq] at h
exact h.2
theorem ltLex_lex {D D' : ℕ} (hD : 0 < D) (hD' : 0 < D') :
∀ (as bs : List ℕ), ltLex D D' as bs = true →
List.Lex (· < ·) (as.map (fun (a : ℕ) => (a : ℝ) / (D : ℝ)))
(bs.map (fun (b : ℕ) => (b : ℝ) / (D' : ℝ)))
| [], [], h => by simp [ltLex] at h
| [], _ :: _, h => by simp [ltLex] at h
| _ :: _, [], h => by simp [ltLex] at h
| a :: as, b :: bs, h => by
simp only [ltLex, Bool.or_eq_true, Bool.and_eq_true, decide_eq_true_eq] at h
have hDr : (0:ℝ) < D := by exact_mod_cast hD
have hD'r : (0:ℝ) < D' := by exact_mod_cast hD'
rw [List.map_cons, List.map_cons]
rcases h with h1 | ⟨h1, h2⟩
· apply List.Lex.rel
have h1' : (a:ℝ) * D' < b * D := by exact_mod_cast h1
rw [div_lt_div_iff₀ hDr hD'r]
exact h1'
· have h1' : (a:ℝ) * D' = b * D := by exact_mod_cast h1
have e : (a:ℝ) / D = b / D' := by
rw [div_eq_div_iff hDr.ne' hD'r.ne']
exact h1'
rw [e]
exact List.Lex.cons (ltLex_lex hD hD' as bs h2)
theorem ltLex_vlist {P Q : IPt} (hP : 0 < P.2) (hQ : 0 < Q.2)
(h : ltLex P.2 Q.2 P.1 Q.1 = true) : vlist P < vlist Q :=
(List.lt_iff_lex_lt _ _).2 (ltLex_lex hP hQ _ _ h)
theorem chain_vlist : ∀ (Z : List IPt), (∀ P ∈ Z, 0 < P.2) → sortedZ Z = true →
List.IsChain (fun P Q => vlist P < vlist Q) Z
| [], _, _ => by simp
| [_], _, _ => by simp
| P :: Q :: rest, hpos, hs => by
simp only [sortedZ, Bool.and_eq_true] at hs
refine List.isChain_cons_cons.2 ⟨ltLex_vlist (hpos P (by simp)) (hpos Q (by simp)) hs.1, ?_⟩
exact chain_vlist (Q :: rest) (fun R hR => hpos R (List.mem_cons_of_mem _ hR)) hs.2
theorem nodup_vlist {Z : List IPt} (hpos : ∀ P ∈ Z, 0 < P.2) (hs : sortedZ Z = true) :
(Z.map vlist).Nodup := by
have hc := chain_vlist Z hpos hs
have hc' : List.IsChain (· < ·) (Z.map vlist) := (List.isChain_map vlist).2 hc
have hpw := List.isChain_iff_pairwise.1 hc'
exact List.Pairwise.imp (fun h => ne_of_lt h) hpw
theorem list8_of_length {l : List ℕ} (hl : l.length = 8) :
∃ a0 a1 a2 a3 a4 a5 a6 a7 : ℕ, l = [a0, a1, a2, a3, a4, a5, a6, a7] := by
rcases l with _ | ⟨a0, _ | ⟨a1, _ | ⟨a2, _ | ⟨a3, _ | ⟨a4, _ | ⟨a5, _ | ⟨a6, _ | ⟨a7, _ | ⟨a8, l⟩⟩⟩⟩⟩⟩⟩⟩⟩
all_goals first
| exact ⟨_, _, _, _, _, _, _, _, rfl⟩
| simp at hl
theorem vlist_eq_of_val {P Q : IPt} (hP : okPt P = true) (hQ : okPt Q = true)
(h : val P = val Q) : vlist P = vlist Q := by
have hP' := hP
have hQ' := hQ
simp only [okPt, Bool.and_eq_true, beq_iff_eq, decide_eq_true_eq] at hP' hQ'
apply List.ext_getElem
· simp [vlist, hP'.1, hQ'.1]
· intro i h1 h2
have hi : i < P.1.length := by simpa [vlist] using h1
have hi' : i < Q.1.length := by simpa [vlist] using h2
have := congrFun h ⟨i, by omega⟩
simp only [val] at this
rw [List.getD_eq_getElem _ _ hi, List.getD_eq_getElem _ _ hi'] at this
simp only [vlist, List.getElem_map]
exact this
theorem checkZ_okPts {Z : List IPt} (h : checkZ Z = true) : okPts Z = true := by
simp only [checkZ, Bool.and_eq_true] at h
exact h.1.1.2
theorem checkZ_length {Z : List IPt} (h : checkZ Z = true) : Z.length = 1024 := by
simp only [checkZ, Bool.and_eq_true, beq_iff_eq] at h
exact h.1.1.1
theorem checkZ_nodup {Z : List IPt} (h : checkZ Z = true) : (Z.map val).Nodup := by
have hok : okPts Z = true := checkZ_okPts h
have hsort : sortedZ Z = true := by
simp only [checkZ, Bool.and_eq_true] at h
exact h.1.2
have hokL : ∀ P ∈ Z, okPt P = true := by
simp only [okPts, List.all_eq_true] at hok
exact hok
have hpos : ∀ P ∈ Z, 0 < P.2 := fun P hP => okPt_pos (hokL P hP)
have hnV := nodup_vlist hpos hsort
have hZ : Z.Nodup := List.Nodup.of_map vlist hnV
refine List.Nodup.map_on ?_ hZ
intro x hx y hy hxy
exact List.inj_on_of_nodup_map hnV hx hy (vlist_eq_of_val (hokL x hx) (hokL y hy) hxy)
theorem checkZ_fin {Z : List IPt} (h : checkZ Z = true) :
∀ z ∈ finsetOf Z, (6060 / 10000 : ℝ) < Antinorm8.fin p₂ z := by
have hok : okPts Z = true := checkZ_okPts h
have hokL : ∀ P ∈ Z, okPt P = true := by
simp only [okPts, List.all_eq_true] at hok
exact hok
have hall : ∀ P ∈ Z, 6060 * 2000 * P.2 < 10000 * finN P.1 := by
simp only [checkZ, Bool.and_eq_true, List.all_eq_true, decide_eq_true_eq] at h
exact h.2
intro z hz
obtain ⟨P, hP, rfl⟩ : ∃ P ∈ Z, val P = z := by
simpa [finsetOf] using hz
have hk := hall P hP
have hDpos : 0 < P.2 := okPt_pos (hokL P hP)
have hL : P.1.length = 8 := by
have := hokL P hP
simp only [okPt, Bool.and_eq_true, beq_iff_eq] at this
exact this.1
obtain ⟨L, D⟩ := P
obtain ⟨N0, N1, N2, N3, N4, N5, N6, N7, rfl⟩ := list8_of_length hL
simp only [finN] at hk
have hDr : (0:ℝ) < D := by exact_mod_cast hDpos
have hk' : (6060 * 2000 * (D:ℝ)) < 10000 * (2000 * (N0:ℝ) + 2000 * (N3:ℝ) + 1000 * (N4:ℝ)
+ 2000 * (N5:ℝ) + 2000 * (N6:ℝ) + 1860 * (N7:ℝ)) := by
exact_mod_cast hk
have e : Antinorm8.fin p₂ (val ([N0, N1, N2, N3, N4, N5, N6, N7], D))
= (2000 * (N0:ℝ) + 2000 * (N3:ℝ) + 1000 * (N4:ℝ)
+ 2000 * (N5:ℝ) + 2000 * (N6:ℝ) + 1860 * (N7:ℝ)) / (2000 * (D:ℝ)) := by
rw [p2v]
simp [Antinorm8.fin, val]
field_simp
ring
rw [e, lt_div_iff₀ (mul_pos (by norm_num) hDr)]
linarith [hk']
theorem fam_mem_finsetOf {Y : List IPt} {x : Fin 8 → ℝ} :
x ∈ finsetOf Y ↔ ∃ P ∈ Y, val P = x := by
unfold finsetOf
simp
theorem fam_finsetOf_nonneg (Y : List IPt) : ∀ x ∈ finsetOf Y, 0 ≤ x := by
intro x hx
obtain ⟨P, _, rfl⟩ := (fam_mem_finsetOf).1 hx
exact val_nonneg P
theorem fam_leaf_mem {Z : List IPt} (hZ : okPts Z = true) {ν c₂ c₃ : ℕ}
{comb : List (ℕ × ℕ × ℕ)} (h : dom Z.length (chunks32 Z) (initI ν c₂ c₃) comb = true) :
init p₂ p₃ y ϖ₂ ϖ₃ ν c₂ c₃ ∈ ê ^ (1 + ν) • PZ (finsetOf Z) := by
have hη : (0:ℝ) < ê ^ (1 + ν) := pow_pos (by norm_num [ê]) _
rw [MaxLeafFormal.Antinorm8.mem_smul_PZ_iff hη, ← val_initI ν c₂ c₃]
exact dom_sound hZ (okPt_initI ν c₂ c₃) h
theorem fam_inf_mem {Z : List IPt} (hZ : okPts Z = true) {comb : List (ℕ × ℕ × ℕ)}
(h : dom Z.length (chunks32 Z) initInfI comb = true) :
initInf p₂ y ∈ ê ^ (ν₀ + 2) • PZ (finsetOf Z) := by
have hη : (0:ℝ) < ê ^ (ν₀ + 2) := pow_pos (by norm_num [ê]) _
rw [MaxLeafFormal.Antinorm8.mem_smul_PZ_iff hη, ← val_initInfI]
exact dom_sound hZ okPt_initInfI h
theorem checkC2_sound {Z : List IPt} (hZ : okPts Z = true) {combos : List (List (ℕ × ℕ × ℕ))}
(h : checkC2 Z.length (chunks32 Z) combos = true) :
(∀ ν ≤ ν₀, init p₂ p₃ y ϖ₂ ϖ₃ ν 0 0 ∈ ê ^ (1 + ν) • PZ (finsetOf Z)) ∧
initInf p₂ y ∈ ê ^ (ν₀ + 2) • PZ (finsetOf Z) := by
unfold checkC2 at h
simp only [Bool.and_eq_true, beq_iff_eq, List.all_eq_true] at h
obtain ⟨⟨hlen, hz⟩, hinf⟩ := h
have h24 : ν₀ = 24 := rfl
refine ⟨fun ν hν => ?_, fam_inf_mem hZ hinf⟩
have hlt : ν < combos.length := by omega
have hmem : ((ν, combos[ν]'hlt) : ℕ × List (ℕ × ℕ × ℕ)) ∈ (List.range 25).zip combos := by
rw [List.mem_iff_getElem]
refine ⟨ν, ?_, ?_⟩
· simp only [List.length_zip, List.length_range, hlen]; omega
· simp only [List.getElem_zip, List.getElem_range]
have h1 := hz _ hmem
dsimp only at h1
exact fam_leaf_mem (ν := ν) (c₂ := 0) (c₃ := 0) (comb := combos[ν]'hlt) hZ h1
theorem checkLeaves_sound {Z : List IPt} (hZ : okPts Z = true)
{entries : List ((ℕ × ℕ × ℕ) × List (ℕ × ℕ × ℕ))}
(h : checkLeaves Z.length (chunks32 Z) entries = true) :
∀ e ∈ entries, LeafFact Z (e.1, ()) := by
intro e he
unfold checkLeaves at h
have h1 : dom Z.length (chunks32 Z) (initI e.1.1 e.1.2.1 e.1.2.2) e.2 = true :=
List.all_eq_true.1 h e he
exact fam_leaf_mem hZ h1
/-- The stage list `[initI] :: stages ++ [Z]` used in the chain. -/
def famL (ν c₂ c₃ : ℕ) (stages : List (List IPt)) (Z : List IPt) : List (List IPt) :=
([initI ν c₂ c₃] :: stages) ++ [Z]
/-- A chain with stages `Y₁, …, Y_{j-1}` (and `Y_j = Z`) gives (C5) with chains of length `j`. -/
theorem chainFact_of_stages {Z : List IPt} (hZ : okPts Z = true) (ν c₂ c₃ : ℕ)
(stages : List (List IPt)) (hst : ∀ Y ∈ stages, okPts Y = true)
(hfacts : ∀ i < stages.length + 1,
StageFact Z (([initI ν c₂ c₃] :: stages).getD i []) ((stages ++ [Z]).getD i [])) :
ChainFact Z ((ν, c₂, c₃), stages.length + 1) := by
have hY0 : finsetOf ((famL ν c₂ c₃ stages Z).getD 0 []) = {val (initI ν c₂ c₃)} := by
simp [famL, finsetOf]
have hYj : finsetOf ((famL ν c₂ c₃ stages Z).getD (stages.length + 1) []) = finsetOf Z := by
simp [famL]
have hYnn : ∀ i < stages.length + 1,
∀ x ∈ finsetOf ((famL ν c₂ c₃ stages Z).getD i []), 0 ≤ x :=
fun i _ x hx => fam_finsetOf_nonneg _ x hx
have hpre : ∀ k < stages.length + 1,
(famL ν c₂ c₃ stages Z).getD k [] = ([initI ν c₂ c₃] :: stages).getD k [] := by
intro k hk
have hk' : k < ([initI ν c₂ c₃] :: stages).length := by simpa using hk
rw [famL, List.getD_eq_getElem?_getD, List.getD_eq_getElem?_getD,
List.getElem?_append_left hk']
have hshift : ∀ i, 1 ≤ i →
(famL ν c₂ c₃ stages Z).getD i [] = (stages ++ [Z]).getD (i - 1) [] := by
intro i hi
obtain ⟨k, rfl⟩ : ∃ k, i = k + 1 := ⟨i - 1, by omega⟩
simp [famL]
have hY : ∀ i, 1 ≤ i → i ≤ stages.length + 1 →
∀ x ∈ finsetOf ((famL ν c₂ c₃ stages Z).getD (i - 1) []), ∀ z ∈ finsetOf Z,
merge p₂ p₃ x z ∈ convexHull ℝ ((finsetOf ((famL ν c₂ c₃ stages Z).getD i []) :
Finset (Fin 8 → ℝ)) : Set (Fin 8 → ℝ)) + Kpos := by
intro i hi1 hi2 x hx z hz
obtain ⟨x', hx', rfl⟩ := (fam_mem_finsetOf).1 hx
obtain ⟨z', hz', rfl⟩ := (fam_mem_finsetOf).1 hz
have hx'' : x' ∈ ([initI ν c₂ c₃] :: stages).getD (i - 1) [] := by
rw [← hpre (i - 1) (by omega)]
exact hx'
have hS := (hfacts (i - 1) (by omega)) x' hx'' z' hz'
rw [hshift i hi1]
exact hS
have key := C5_of_stages (p₂ := p₂) (p₃ := p₃)
⟨by norm_num [p₂], by norm_num [p₂, p₃], by norm_num [p₃]⟩
(fam_finsetOf_nonneg Z) (val (initI ν c₂ c₃)) (val_nonneg _) (stages.length + 1)
(fun i => finsetOf ((famL ν c₂ c₃ stages Z).getD i []))
hY0 hYj hYnn hY
unfold ChainFact
intro Qs hlen hQ
have key' := key Qs hlen hQ
rw [val_initI ν c₂ c₃] at key'
exact key'
theorem checkChain1_sound {Z : List IPt} (hZ : okPts Z = true)
{entries : List ((ℕ × ℕ × ℕ) × List (List (ℕ × ℕ × ℕ)))}
(h : checkChain1 Z.length (chunks32 Z) Z entries = true) :
∀ e ∈ entries, ChainFact Z (e.1, 1) := by
intro e he
unfold checkChain1 at h
have h1 : checkBlock Z.length (chunks32 Z) Z [initI e.1.1 e.1.2.1 e.1.2.2] [e.2] = true :=
List.all_eq_true.1 h e he
have hxs : okPts [initI e.1.1 e.1.2.1 e.1.2.2] = true := by
simp [okPts, okPt_initI]
have hfacts : ∀ i < ([] : List (List IPt)).length + 1,
StageFact Z (([initI e.1.1 e.1.2.1 e.1.2.2] :: []).getD i [])
((([] : List (List IPt)) ++ [Z]).getD i []) := by
intro i hi
have hi0 : i = 0 := by simp at hi; omega
subst hi0
exact checkBlock_sound hZ hZ hxs h1
exact chainFact_of_stages hZ e.1.1 e.1.2.1 e.1.2.2 [] (by simp) hfacts
/-- Blocks of `B` consecutive elements cover a list. -/
theorem cover_blocks {α : Type} (P : α → Prop) (X : List α) (B : ℕ) (hB : 0 < B)
(h : ∀ r < (X.length + B - 1) / B, ∀ x ∈ (X.drop (B * r)).take B, P x) :
∀ x ∈ X, P x := by
intro x hx
obtain ⟨i, hi, rfl⟩ := List.mem_iff_getElem.mp hx
have hdm := Nat.div_add_mod i B
have hmod := Nat.mod_lt i hB
have hr : i / B < (X.length + B - 1) / B := by
have h1 : (i + B) / B = i / B + 1 := Nat.add_div_right i hB
have h2 : (i + B) / B ≤ (X.length + B - 1) / B := by
apply Nat.div_le_div_right
omega
omega
apply h (i / B) hr
apply List.mem_iff_getElem.mpr
refine ⟨i - B * (i / B), ?_, ?_⟩
· simp only [List.length_take, List.length_drop]
omega
· simp only [List.getElem_take, List.getElem_drop]
congr 1
omega
/-- `Init(ν) ∈ ê^{1+ν} 𝒫_Z` for every `ν`, from (C2) and `ê < 1`. -/
theorem init00_mem {Z : Finset (Fin 8 → ℝ)} (hZ0 : ∀ z ∈ Z, 0 ≤ z)
(C2 : (∀ ν ≤ ν₀, init p₂ p₃ y ϖ₂ ϖ₃ ν 0 0 ∈ ê ^ (1 + ν) • PZ Z) ∧
initInf p₂ y ∈ ê ^ (ν₀ + 2) • PZ Z) (ν : ℕ) :
init p₂ p₃ y ϖ₂ ϖ₃ ν 0 0 ∈ ê ^ (1 + ν) • PZ Z := by
obtain ⟨hp3, -, ⟨hê, hêq⟩, -, -⟩ := rsc_side
have hê1 : ê ≤ 1 := by linarith [hp3.1, hp3.2.1, hp3.2.2]
by_cases hν : ν ≤ ν₀
· exact C2.1 ν hν
· have hsplit : init p₂ p₃ y ϖ₂ ϖ₃ ν 0 0
= initInf p₂ y + ![0, 0, 0, 0, (1/2 : ℝ) ^ ν, 0, 0, 0] := by
funext i; fin_cases i <;> simp [init, initInf]
have hK : 0 ≤ (![0, 0, 0, 0, (1/2 : ℝ) ^ ν, 0, 0, 0] : Fin 8 → ℝ) := by
have h4 : (0 : ℝ) ≤ (1/2 : ℝ) ^ ν := pow_nonneg (by norm_num) _
intro i; fin_cases i <;> simpa using h4
rw [hsplit]
refine MaxLeafFormal.Antinorm8.smul_PZ_mono hZ0 (pow_pos hê _) ?_
(MaxLeafFormal.Antinorm8.smul_PZ_add_Kpos (pow_pos hê _) C2.2 (MaxLeafFormal.Antinorm8.Kpos_of_nonneg hK))
exact pow_le_pow_of_le_one hê.le hê1 (by omega)
/-- A fold that starts in `𝒫_Z` stays in `𝒫_Z` (Step 1 with `η = η' = 1`, using (C1)). -/
theorem foldl_mem_PZ {Z : Finset (Fin 8 → ℝ)} (hZ0 : ∀ z ∈ Z, 0 ≤ z)
(C1 : ∀ z ∈ Z, ∀ z' ∈ Z, merge p₂ p₃ z z' ∈ PZ Z) :
∀ (Qs : List (Fin 8 → ℝ)) (X : Fin 8 → ℝ), X ∈ PZ Z → (∀ Q ∈ Qs, Q ∈ PZ Z ∧ 0 ≤ Q) →
Qs.foldl (merge p₂ p₃) X ∈ PZ Z := by
obtain ⟨hp3, -⟩ := rsc_side
have hp : 0 < p₂ ∧ p₂ ≤ p₃ ∧ p₃ ≤ 1 := ⟨hp3.1, hp3.2.1, by linarith [hp3.2.2]⟩
intro Qs
induction Qs with
| nil => intro X hX _; exact hX
| cons Q Qs ih =>
intro X hX hQs
rw [List.foldl_cons]
have hX1 : X ∈ (1:ℝ) • PZ Z := by rw [one_smul]; exact hX
have hQ1 : Q ∈ (1:ℝ) • PZ Z := by rw [one_smul]; exact (hQs Q (by simp)).1
have hm := merge_mem_smul_PZ hp hZ0 C1 one_pos one_pos hX1 hQ1 (hQs Q (by simp)).2
rw [mul_one, one_smul] at hm
exact ih _ hm (fun Q' hQ' => hQs Q' (by simp [hQ']))
theorem foldl_merge_add_left (Qs : List (Fin 8 → ℝ)) (X X' : Fin 8 → ℝ) :
Qs.foldl (merge p₂ p₃) (X + X') = Qs.foldl (merge p₂ p₃) X + Qs.foldl (merge p₂ p₃) X' := by
induction Qs generalizing X X' with
| nil => rfl
| cons Q Qs ih =>
simp only [List.foldl_cons]
rw [merge_add_left]
exact ih _ _
theorem foldl_merge_smul_left (Qs : List (Fin 8 → ℝ)) (a : ℝ) (X : Fin 8 → ℝ) :
Qs.foldl (merge p₂ p₃) (a • X) = a • Qs.foldl (merge p₂ p₃) X := by
induction Qs generalizing X with
| nil => rfl
| cons Q Qs ih =>
simp only [List.foldl_cons]
rw [merge_smul_left]
exact ih _
/-! ### Helpers for `combWitness_sound` -/
theorem mem_lattice5 {ν c₂ c₃ : ℕ} (h1 : 1 ≤ ν) (h2 : ν ≤ 36) (h3 : 1 ≤ c₂ + c₃)
(h4 : c₂ + c₃ ≤ ν) : (ν, c₂, c₃) ∈ lattice5 := by
unfold lattice5
rw [List.mem_flatMap]
refine ⟨ν - 1, List.mem_range.mpr (by omega), ?_⟩
rw [List.mem_flatMap]
refine ⟨c₂, List.mem_range.mpr (by omega), ?_⟩
rw [List.mem_map]
refine ⟨c₃, ?_, ?_⟩
· rw [List.mem_filter]
exact ⟨List.mem_range.mpr (by omega), decide_eq_true h3⟩
· show (ν - 1 + 1, c₂, c₃) = (ν, c₂, c₃)
rw [Nat.sub_add_cancel h1]
theorem mem_lattice4 {ν c₂ c₃ : ℕ} (h1 : 4 ≤ ν) (h2 : ν ≤ 36) (h3 : 1 ≤ c₂ + c₃)
(h4 : c₂ + c₃ ≤ ν - 1) : (ν, c₂, c₃) ∈ lattice4 := by
unfold lattice4
rw [List.mem_flatMap]
refine ⟨ν - 4, List.mem_range.mpr (by omega), ?_⟩
rw [List.mem_flatMap]
refine ⟨c₂, List.mem_range.mpr (by omega), ?_⟩
rw [List.mem_map]
refine ⟨c₃, ?_, ?_⟩
· rw [List.mem_filter]
exact ⟨List.mem_range.mpr (by omega), decide_eq_true h3⟩
· show (ν - 4 + 4, c₂, c₃) = (ν, c₂, c₃)
rw [Nat.sub_add_cancel h1]
def scS (l : List ((ℕ × ℕ) × ℕ × ℕ)) : ℕ × ℕ :=
l.foldr (fun e r => (r.1 * e.2.2 + e.2.1 * r.2, r.2 * e.2.2)) (0, 1)
def scG (g : ℕ × ℕ → ℕ × ℕ) (l : List ((ℕ × ℕ) × ℕ × ℕ)) : ℕ × ℕ :=
l.foldr (fun e r => (r.1 * (e.2.2 * (g e.1).2) + e.2.1 * (g e.1).1 * r.2,
r.2 * (e.2.2 * (g e.1).2))) (0, 1)
theorem scS_spec : ∀ l : List ((ℕ × ℕ) × ℕ × ℕ), (∀ e ∈ l, 0 < e.2.2) →
0 < (scS l).2 ∧ ((scS l).1 : ℝ) / ((scS l).2 : ℝ)
= (l.map fun e => ((e.2.1 : ℝ) / e.2.2)).sum := by
intro l
induction l with
| nil => intro _; simp [scS]
| cons e l ih =>
intro hl
obtain ⟨hS2, hval⟩ := ih (fun e' he' => hl e' (by simp [he']))
have hb : 0 < e.2.2 := hl e (by simp)
have hb' : (e.2.2 : ℝ) ≠ 0 := by exact_mod_cast hb.ne'
have hS2' : ((scS l).2 : ℝ) ≠ 0 := by exact_mod_cast hS2.ne'
have hfold : scS (e :: l) = ((scS l).1 * e.2.2 + e.2.1 * (scS l).2, (scS l).2 * e.2.2) := rfl
rw [hfold, List.map_cons, List.sum_cons, ← hval]
refine ⟨Nat.mul_pos hS2 hb, ?_⟩
dsimp only
push_cast
field_simp
ring
theorem scG_spec (g : ℕ × ℕ → ℕ × ℕ) (hg : ∀ c, 0 < (g c).2) :
∀ l : List ((ℕ × ℕ) × ℕ × ℕ), (∀ e ∈ l, 0 < e.2.2) →
0 < (scG g l).2 ∧ ((scG g l).1 : ℝ) / ((scG g l).2 : ℝ)
= (l.map fun e => ((e.2.1 : ℝ) / e.2.2) * (((g e.1).1 : ℝ) / ((g e.1).2 : ℝ))).sum := by
intro l
induction l with
| nil => intro _; simp [scG]
| cons e l ih =>
intro hl
obtain ⟨hS2, hval⟩ := ih (fun e' he' => hl e' (by simp [he']))
have hb : 0 < e.2.2 := hl e (by simp)
have hG : 0 < (g e.1).2 := hg _
have hb' : (e.2.2 : ℝ) ≠ 0 := by exact_mod_cast hb.ne'
have hG' : ((g e.1).2 : ℝ) ≠ 0 := by exact_mod_cast hG.ne'
have hS2' : ((scG g l).2 : ℝ) ≠ 0 := by exact_mod_cast hS2.ne'
have hfold : scG g (e :: l) = ((scG g l).1 * (e.2.2 * (g e.1).2) + e.2.1 * (g e.1).1 * (scG g l).2,
(scG g l).2 * (e.2.2 * (g e.1).2)) := rfl
rw [hfold, List.map_cons, List.sum_cons, ← hval]
refine ⟨Nat.mul_pos hS2 (Nat.mul_pos hb hG), ?_⟩
dsimp only
push_cast
field_simp
ring
theorem sc_uF_ratio (c₁ c₂ : ℕ) :
(1 - p₂) ^ c₁ * (1 - p₃) ^ c₂ = ((uF c₁ c₂).1 : ℝ) / ((uF c₁ c₂).2 : ℝ) := by
simp only [uF, p2v, p3v]
push_cast
rw [show (1:ℝ) - 7/100 = 93/100 by norm_num, show (1:ℝ) - 77/1000 = 923/1000 by norm_num,
div_pow, div_pow, div_mul_div_comm]
theorem sc_wF_ratio (c₁ c₂ : ℕ) :
ϖ₂ ^ c₁ * ϖ₃ ^ c₂ = ((wF c₁ c₂).1 : ℝ) / ((wF c₁ c₂).2 : ℝ) := by
simp only [wF, ϖ₂, ϖ₃]
push_cast
rw [pow_add, div_pow, div_pow, div_mul_div_comm]
def vecN (ν : ℕ) (x z : ℝ) : Fin 8 → ℝ :=
![x * (y / 2), x * (p₂ / 2), 0, 0, (1/2 : ℝ) ^ ν * z, 0, 0, 0]
theorem init_eq_vecN (ν c₂ c₃ : ℕ) :
init p₂ p₃ y ϖ₂ ϖ₃ ν c₂ c₃ = vecN ν ((1 - p₂) ^ c₂ * (1 - p₃) ^ c₃) (ϖ₂ ^ c₂ * ϖ₃ ^ c₃) := by
funext i; fin_cases i <;> simp [init, vecN] <;> ring
theorem vecN_smul (ν : ℕ) (c x z : ℝ) : c • vecN ν x z = vecN ν (c * x) (c * z) := by
funext i; fin_cases i <;> simp [vecN] <;> ring
theorem vecN_add (ν : ℕ) (x z x' z' : ℝ) :
vecN ν x z + vecN ν x' z' = vecN ν (x + x') (z + z') := by
funext i; fin_cases i <;> simp [vecN] <;> ring
theorem vecN_zero (ν : ℕ) : vecN ν 0 0 = 0 := by
funext i; fin_cases i <;> simp [vecN]
theorem sc_listSum (ν : ℕ) : ∀ l : List ((ℕ × ℕ) × ℕ × ℕ),
(l.map fun e => ((e.2.1 : ℝ) / e.2.2) • init p₂ p₃ y ϖ₂ ϖ₃ ν e.1.1 e.1.2).sum
= vecN ν (l.map fun e => ((e.2.1 : ℝ) / e.2.2) * ((1 - p₂) ^ e.1.1 * (1 - p₃) ^ e.1.2)).sum
(l.map fun e => ((e.2.1 : ℝ) / e.2.2) * (ϖ₂ ^ e.1.1 * ϖ₃ ^ e.1.2)).sum := by
intro l
induction l with
| nil => simp only [List.map_nil, List.sum_nil, vecN_zero]
| cons e l ih =>
simp only [List.map_cons, List.sum_cons]
rw [ih, init_eq_vecN, vecN_smul, vecN_add]
/-- `eq:rsc-init-linear`: a convex-combination witness writes `Init~(ν; c₂, c₃)` as the
combination of the `Init~(ν; c₂', c₃')`. -/
theorem combWitness_sound {c₂ c₃ : ℕ} {comps : List ((ℕ × ℕ) × ℕ × ℕ)}
(h : combWitness c₂ c₃ comps = true) (ν : ℕ) :
(∀ e ∈ comps, 0 ≤ ((e.2.1 : ℝ) / e.2.2)) ∧ (comps.map fun e => ((e.2.1 : ℝ) / e.2.2)).sum = 1 ∧
init p₂ p₃ y ϖ₂ ϖ₃ ν c₂ c₃ =
(comps.map fun e => ((e.2.1 : ℝ) / e.2.2) • init p₂ p₃ y ϖ₂ ϖ₃ ν e.1.1 e.1.2).sum := by
unfold combWitness at h
simp only [Bool.and_eq_true, decide_eq_true_eq, List.all_eq_true] at h
obtain ⟨⟨⟨h1, h2⟩, h3⟩, h4⟩ := h
have hpos : ∀ e ∈ comps, 0 < e.2.2 := h1
have h2' : (scS comps).1 = (scS comps).2 := h2
have h3' : (scG (fun c => uF c.1 c.2) comps).1 * (uF c₂ c₃).2
= (uF c₂ c₃).1 * (scG (fun c => uF c.1 c.2) comps).2 := h3
have h4' : (scG (fun c => wF c.1 c.2) comps).1 * (wF c₂ c₃).2
= (wF c₂ c₃).1 * (scG (fun c => wF c.1 c.2) comps).2 := h4
obtain ⟨hSpos, hSval⟩ := scS_spec comps hpos
obtain ⟨hUpos, hUval⟩ := scG_spec (fun c => uF c.1 c.2)
(fun c => by show 0 < (uF c.1 c.2).2; simp only [uF]; positivity) comps hpos
obtain ⟨hWpos, hWval⟩ := scG_spec (fun c => wF c.1 c.2)
(fun c => by show 0 < (wF c.1 c.2).2; simp only [wF]; positivity) comps hpos
have hSne : ((scS comps).2 : ℝ) ≠ 0 := by exact_mod_cast hSpos.ne'
have hUne : ((scG (fun c => uF c.1 c.2) comps).2 : ℝ) ≠ 0 := by exact_mod_cast hUpos.ne'
have hWne : ((scG (fun c => wF c.1 c.2) comps).2 : ℝ) ≠ 0 := by exact_mod_cast hWpos.ne'
have hu0 : ((uF c₂ c₃).2 : ℝ) ≠ 0 := by
have : 0 < (uF c₂ c₃).2 := by simp only [uF]; positivity
exact_mod_cast this.ne'
have hw0 : ((wF c₂ c₃).2 : ℝ) ≠ 0 := by
have : 0 < (wF c₂ c₃).2 := by simp only [wF]; positivity
exact_mod_cast this.ne'
have hsum1 : (comps.map fun e => ((e.2.1 : ℝ) / e.2.2)).sum = 1 := by
have hc : ((scS comps).1 : ℝ) = ((scS comps).2 : ℝ) := by rw [h2']
rw [hc, div_self hSne] at hSval
exact hSval.symm
have hsumU : (comps.map fun e => ((e.2.1 : ℝ) / e.2.2) * ((1 - p₂) ^ e.1.1 * (1 - p₃) ^ e.1.2)).sum
= (1 - p₂) ^ c₂ * (1 - p₃) ^ c₃ := by
simp only [sc_uF_ratio]
rw [← hUval, div_eq_div_iff hUne hu0]
exact_mod_cast h3'
have hsumW : (comps.map fun e => ((e.2.1 : ℝ) / e.2.2) * (ϖ₂ ^ e.1.1 * ϖ₃ ^ e.1.2)).sum
= ϖ₂ ^ c₂ * ϖ₃ ^ c₃ := by
simp only [sc_wF_ratio]
rw [← hWval, div_eq_div_iff hWne hw0]
exact_mod_cast h4'
refine ⟨fun e _ => div_nonneg (Nat.cast_nonneg _) (Nat.cast_nonneg _), hsum1, ?_⟩
rw [init_eq_vecN, sc_listSum ν comps, hsumU, hsumW]
theorem rsc5_list_sum_eq {α β : Type*} [AddCommMonoid β] (L : List α) (g : α → β) :
(L.map g).sum = ∑ i : Fin L.length, g (L[i]) := by
induction L with
| nil => simp
| cons a L ih =>
rw [List.map_cons, List.sum_cons, ih]
show _ = ∑ i : Fin (L.length + 1), g (a :: L)[i]
rw [Fin.sum_univ_succ]
simp
theorem rsc5_convex_sum {V : Type*} [AddCommGroup V] [Module ℝ V] {S : Set V} (hS : Convex ℝ S)
{α : Type*} (L : List α) (w : α → ℝ) (z : α → V) (hw : ∀ a ∈ L, 0 ≤ w a)
(hsum : (L.map w).sum = 1) (hz : ∀ a ∈ L, z a ∈ S) :
(L.map fun a => w a • z a).sum ∈ S := by
rw [rsc5_list_sum_eq L (fun a => w a • z a)]
rw [rsc5_list_sum_eq L w] at hsum
have key := hS.sum_mem (t := (Finset.univ : Finset (Fin L.length)))
(w := fun i => w L[i]) (z := fun i => z L[i])
(fun i _ => hw _ (List.getElem_mem _)) hsum (fun i _ => hz _ (List.getElem_mem _))
exact key
theorem rsc5_foldl_sum {α : Type*} (Qs : List (Fin 8 → ℝ)) (L : List α) (w : α → ℝ)
(z : α → Fin 8 → ℝ) :
Qs.foldl (merge p₂ p₃) (L.map fun a => w a • z a).sum =
(L.map fun a => w a • Qs.foldl (merge p₂ p₃) (z a)).sum := by
have h0 : Qs.foldl (merge p₂ p₃) 0 = 0 := by
simpa using foldl_merge_smul_left Qs 0 0
induction L with
| nil => simpa using h0
| cons a L ih =>
simp only [List.map_cons, List.sum_cons]
rw [foldl_merge_add_left, ih, foldl_merge_smul_left]
theorem rsc5_foldl_conv {S : Set (Fin 8 → ℝ)} (hS : Convex ℝ S) (Qs : List (Fin 8 → ℝ))
{α : Type*} (L : List α) (w : α → ℝ) (z : α → Fin 8 → ℝ) (hw : ∀ a ∈ L, 0 ≤ w a)
(hsum : (L.map w).sum = 1) (hx : ∀ a ∈ L, Qs.foldl (merge p₂ p₃) (z a) ∈ S) :
Qs.foldl (merge p₂ p₃) (L.map fun a => w a • z a).sum ∈ S := by
rw [rsc5_foldl_sum]
exact rsc5_convex_sum hS L w (fun a => Qs.foldl (merge p₂ p₃) (z a)) hw hsum hx
theorem rsc5_smul_sum {α : Type*} (c : ℝ) (L : List α) (w : α → ℝ) (z : α → Fin 8 → ℝ) :
c • (L.map fun a => w a • z a).sum = (L.map fun a => w a • (c • z a)).sum := by
induction L with
| nil => simp
| cons a L ih =>
simp only [List.map_cons, List.sum_cons, smul_add, ih, smul_comm c (w a) (z a)]
theorem rsc5_finset_nonneg (Z : List IPt) : ∀ z ∈ finsetOf Z, 0 ≤ z := by
intro z hz
unfold finsetOf at hz
obtain ⟨P, -, rfl⟩ := List.mem_map.1 (List.mem_toFinset.1 hz)
exact val_nonneg P
theorem rsc5_chain {Z : List IPt}
(C1 : ∀ z ∈ finsetOf Z, ∀ z' ∈ finsetOf Z, merge p₂ p₃ z z' ∈ PZ (finsetOf Z))
{e : (ℕ × ℕ × ℕ) × ℕ} (hc : ChainFact Z e) {Qs : List (Fin 8 → ℝ)} (hlen : e.2 ≤ Qs.length)
(hQ : ∀ Q ∈ Qs, Q ∈ PZ (finsetOf Z) ∧ 0 ≤ Q) :
Qs.foldl (merge p₂ p₃) ((ê ^ (1 + e.1.1))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ e.1.1 e.1.2.1 e.1.2.2)
∈ PZ (finsetOf Z) := by
have hsplit := List.take_append_drop e.2 Qs
have hlt : (Qs.take e.2).length = e.2 := by simp [hlen]
rw [← hsplit, List.foldl_append]
exact foldl_mem_PZ (rsc5_finset_nonneg Z) C1 _ _
(hc _ hlt (fun Q hQm => hQ Q (List.mem_of_mem_take hQm)))
(fun Q hQm => hQ Q (List.mem_of_mem_drop hQm))
theorem rsc5_shape5 (T : List ((ℕ × ℕ × ℕ) × ℕ)) (pt : ℕ × ℕ × ℕ) (dat : List ℕ)
(h : latOK5 T pt dat = true) :
(∃ k, dat = [0, k]) ∨ (∃ m rest, dat = 1 :: m :: rest) := by
rcases dat with _ | ⟨a, _ | ⟨b, _ | ⟨c, rest⟩⟩⟩
· simp [latOK5] at h
· simp [latOK5] at h
· rcases a with _ | _ | a
· exact Or.inl ⟨b, rfl⟩
· exact Or.inr ⟨b, [], rfl⟩
· simp [latOK5] at h
· rcases a with _ | _ | a
· simp [latOK5] at h
· exact Or.inr ⟨b, c :: rest, rfl⟩
· simp [latOK5] at h
theorem rsc4_shape4 (T : List ((ℕ × ℕ × ℕ) × Unit)) (pt : ℕ × ℕ × ℕ) (dat : List ℕ)
(h : latOK4 T pt dat = true) :
(∃ k, dat = [0, k]) ∨ (∃ m rest, dat = 1 :: m :: rest) := by
rcases dat with _ | ⟨a, _ | ⟨b, _ | ⟨c, rest⟩⟩⟩
· simp [latOK4] at h
· simp [latOK4] at h
· rcases a with _ | _ | a
· exact Or.inl ⟨b, rfl⟩
· exact Or.inr ⟨b, [], rfl⟩
· simp [latOK4] at h
· rcases a with _ | _ | a
· simp [latOK4] at h
· exact Or.inr ⟨b, c :: rest, rfl⟩
· simp [latOK4] at h
theorem rsc5_point {Z : List IPt}
(C1 : ∀ z ∈ finsetOf Z, ∀ z' ∈ finsetOf Z, merge p₂ p₃ z z' ∈ PZ (finsetOf Z))
(h00 : ∀ ν, init p₂ p₃ y ϖ₂ ϖ₃ ν 0 0 ∈ ê ^ (1 + ν) • PZ (finsetOf Z))
{T : List ((ℕ × ℕ × ℕ) × ℕ)} (hT : ∀ e ∈ T, ChainFact Z e) (ν c₂ c₃ : ℕ)
(dat : List ℕ) (hok : latOK5 T (ν, c₂, c₃) dat = true)
(Qs : List (Fin 8 → ℝ)) (hlen : Qs.length = jTarget ν c₂)
(hQ : ∀ Q ∈ Qs, Q ∈ PZ (finsetOf Z) ∧ 0 ≤ Q) :
Qs.foldl (merge p₂ p₃) ((ê ^ (1 + ν))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ ν c₂ c₃) ∈ PZ (finsetOf Z) := by
have hê : 0 < ê := by norm_num [ê]
have hη : 0 < ê ^ (1 + ν) := pow_pos hê _
have hS : Convex ℝ (PZ (finsetOf Z)) := MaxLeafFormal.Antinorm8.convex_hullKpos (finsetOf Z)
have hchain : ∀ t : (ℕ × ℕ × ℕ) × ℕ, ChainFact Z t → t.1.1 = ν → t.2 ≤ jTarget ν c₂ →
Qs.foldl (merge p₂ p₃) ((ê ^ (1 + ν))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ ν t.1.2.1 t.1.2.2)
∈ PZ (finsetOf Z) := by
intro t hc hn hj
have ht : ((ν, t.1.2.1, t.1.2.2), t.2) = t := Prod.ext (Prod.ext hn.symm rfl) rfl
have hc' : ChainFact Z ((ν, t.1.2.1, t.1.2.2), t.2) := by rw [ht]; exact hc
exact rsc5_chain C1 hc' (by rw [hlen]; exact hj) hQ
rcases rsc5_shape5 T _ dat hok with ⟨k, rfl⟩ | ⟨m, rest, rfl⟩
· simp only [latOK5, Bool.and_eq_true, decide_eq_true_eq] at hok
obtain ⟨⟨hk, hpt⟩, hj⟩ := hok
have hmem : T.getD k ((0, 0, 0), 0) ∈ T := by
rw [List.getD_eq_getElem _ _ hk]; exact List.getElem_mem _
have key := hchain _ (hT _ hmem) (by rw [hpt]) hj
rw [hpt] at key
exact key
· simp only [latOK5, Bool.and_eq_true, List.all_eq_true, Bool.or_eq_true,
decide_eq_true_eq] at hok
obtain ⟨hcomp, hB⟩ := hok
obtain ⟨hnn, hsum, heq⟩ := combWitness_sound hB ν
rw [heq, rsc5_smul_sum]
refine rsc5_foldl_conv hS Qs _ (fun a : (ℕ × ℕ) × ℕ × ℕ => ((a.2.1 : ℝ) / a.2.2))
(fun a : (ℕ × ℕ) × ℕ × ℕ => (ê ^ (1 + ν))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ ν a.1.1 a.1.2)
hnn hsum ?_
intro a ha
obtain ⟨e0, he0, rfl⟩ := List.mem_map.1 ha
rcases hcomp e0 he0 with h0 | ⟨⟨⟨h1, hlt⟩, hn⟩, hle⟩
· have hc0 : compPt T 0 e0 = (0, 0) := by simp [compPt, h0]
show Qs.foldl (merge p₂ p₃)
((ê ^ (1 + ν))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ ν (compPt T 0 e0).1 (compPt T 0 e0).2)
∈ PZ (finsetOf Z)
rw [hc0]
exact foldl_mem_PZ (rsc5_finset_nonneg Z) C1 _ _
((MaxLeafFormal.Antinorm8.mem_smul_PZ_iff hη).1 (h00 ν)) hQ
· have hc0 : compPt T 0 e0 = ((T.getD e0.2.1 ((0, 0, 0), 0)).1.2.1,
(T.getD e0.2.1 ((0, 0, 0), 0)).1.2.2) := by simp [compPt, h1]
have hmem : T.getD e0.2.1 ((0, 0, 0), 0) ∈ T := by
rw [List.getD_eq_getElem _ _ hlt]; exact List.getElem_mem _
show Qs.foldl (merge p₂ p₃)
((ê ^ (1 + ν))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ ν (compPt T 0 e0).1 (compPt T 0 e0).2)
∈ PZ (finsetOf Z)
rw [hc0]
exact hchain (T.getD e0.2.1 ((0, 0, 0), 0)) (hT _ hmem) hn hle
theorem rsc4_dat {T : List ((ℕ × ℕ × ℕ) × Unit)} {wit : List (List ℕ)}
(h : checkLattice4 T wit = true) {ν c₂ c₃ : ℕ} (hm : (ν, c₂, c₃) ∈ lattice4) :
∃ dat, latOK4 T (ν, c₂, c₃) dat = true := by
rw [checkLattice4, Bool.and_eq_true, beq_iff_eq, List.all_eq_true] at h
obtain ⟨hlen, hall⟩ := h
obtain ⟨i, hi, hiEq⟩ := List.getElem_of_mem hm
have hi' : i < wit.length := by rw [← hlen]; exact hi
have hi2 : i < (lattice4.zip wit).length := by
rw [List.length_zip, hlen, min_self]; exact hi'
have hz := hall _ (List.getElem_mem hi2)
simp only [List.getElem_zip] at hz
rw [hiEq] at hz
exact ⟨_, hz⟩
theorem rsc4_point {Z : List IPt}
(h00 : ∀ ν, init p₂ p₃ y ϖ₂ ϖ₃ ν 0 0 ∈ ê ^ (1 + ν) • PZ (finsetOf Z))
{T : List ((ℕ × ℕ × ℕ) × Unit)} (hT : ∀ e ∈ T, LeafFact Z e) (ν c₂ c₃ : ℕ)
(dat : List ℕ) (hok : latOK4 T (ν, c₂, c₃) dat = true) :
init p₂ p₃ y ϖ₂ ϖ₃ ν c₂ c₃ ∈ ê ^ (1 + ν) • PZ (finsetOf Z) := by
have hS : Convex ℝ (ê ^ (1 + ν) • PZ (finsetOf Z)) :=
(MaxLeafFormal.Antinorm8.convex_hullKpos (finsetOf Z)).smul _
have hleaf : ∀ t : (ℕ × ℕ × ℕ) × Unit, t ∈ T → t.1.1 = ν →
init p₂ p₃ y ϖ₂ ϖ₃ ν t.1.2.1 t.1.2.2 ∈ ê ^ (1 + ν) • PZ (finsetOf Z) := by
intro t ht hn
have ht' : ((ν, t.1.2.1, t.1.2.2), t.2) = t := Prod.ext (Prod.ext hn.symm rfl) rfl
have hc : LeafFact Z ((ν, t.1.2.1, t.1.2.2), t.2) := by rw [ht']; exact hT t ht
exact hc
rcases rsc4_shape4 T _ dat hok with ⟨k, rfl⟩ | ⟨m, rest, rfl⟩
· simp only [latOK4, Bool.and_eq_true, decide_eq_true_eq] at hok
obtain ⟨hk, hpt⟩ := hok
have hmem : T.getD k ((0, 0, 0), ()) ∈ T := by
rw [List.getD_eq_getElem _ _ hk]; exact List.getElem_mem _
have key := hleaf _ hmem (by rw [hpt])
rw [hpt] at key
exact key
· simp only [latOK4, Bool.and_eq_true, List.all_eq_true, Bool.or_eq_true,
decide_eq_true_eq] at hok
obtain ⟨hcomp, hB⟩ := hok
obtain ⟨hnn, hsum, heq⟩ := combWitness_sound hB ν
rw [heq]
refine rsc5_convex_sum hS _ (fun a : (ℕ × ℕ) × ℕ × ℕ => ((a.2.1 : ℝ) / a.2.2))
(fun a : (ℕ × ℕ) × ℕ × ℕ => init p₂ p₃ y ϖ₂ ϖ₃ ν a.1.1 a.1.2) hnn hsum ?_
intro a ha
obtain ⟨e0, he0, rfl⟩ := List.mem_map.1 ha
rcases hcomp e0 he0 with h0 | ⟨⟨h1, hlt⟩, hn⟩
· have hc0 : compPt T () e0 = (0, 0) := by simp [compPt, h0]
show init p₂ p₃ y ϖ₂ ϖ₃ ν (compPt T () e0).1 (compPt T () e0).2
∈ ê ^ (1 + ν) • PZ (finsetOf Z)
rw [hc0]
exact h00 ν
· have hc0 : compPt T () e0 = ((T.getD e0.2.1 ((0, 0, 0), ())).1.2.1,
(T.getD e0.2.1 ((0, 0, 0), ())).1.2.2) := by simp [compPt, h1]
have hmem : T.getD e0.2.1 ((0, 0, 0), ()) ∈ T := by
rw [List.getD_eq_getElem _ _ hlt]; exact List.getElem_mem _
show init p₂ p₃ y ϖ₂ ϖ₃ ν (compPt T () e0).1 (compPt T () e0).2
∈ ê ^ (1 + ν) • PZ (finsetOf Z)
rw [hc0]
exact hleaf (T.getD e0.2.1 ((0, 0, 0), ())) hmem hn
/-- (C5) at every lattice point, from the lattice check. -/
theorem checkLattice5_sound {Z : List IPt} (hZ : okPts Z = true)
(C1 : ∀ z ∈ finsetOf Z, ∀ z' ∈ finsetOf Z, merge p₂ p₃ z z' ∈ PZ (finsetOf Z))
(h00 : ∀ ν, init p₂ p₃ y ϖ₂ ϖ₃ ν 0 0 ∈ ê ^ (1 + ν) • PZ (finsetOf Z))
{T : List ((ℕ × ℕ × ℕ) × ℕ)} (hT : ∀ e ∈ T, ChainFact Z e)
{wit : List (List ℕ)} (h : checkLattice5 T wit = true) :
∀ ν, 1 ≤ ν → ν ≤ νE → ∀ c₂ c₃, 1 ≤ c₂ + c₃ → c₂ + c₃ ≤ ν →
∀ Qs : List (Fin 8 → ℝ), Qs.length = (if c₂ = 0 then jOf d₃ ν else jOf d₂ ν) →
(∀ Q ∈ Qs, Q ∈ PZ (finsetOf Z) ∧ 0 ≤ Q) →
Qs.foldl (merge p₂ p₃) ((ê ^ (1 + ν))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ ν c₂ c₃) ∈ PZ (finsetOf Z) := by
intro ν hν1 hνE c₂ c₃ hc1 hc2 Qs hlen hQ
have hν36 : ν ≤ 36 := by simpa [νE] using hνE
have hmem : (ν, c₂, c₃) ∈ lattice5 := mem_lattice5 hν1 hν36 hc1 hc2
rw [checkLattice5, Bool.and_eq_true, beq_iff_eq, List.all_eq_true] at h
obtain ⟨hlen5, hall⟩ := h
obtain ⟨i, hi, hiEq⟩ := List.getElem_of_mem hmem
have hi' : i < wit.length := by rw [← hlen5]; exact hi
have hi2 : i < (lattice5.zip wit).length := by
rw [List.length_zip, hlen5, min_self]; exact hi'
have hz := hall _ (List.getElem_mem hi2)
simp only [List.getElem_zip] at hz
rw [hiEq] at hz
exact rsc5_point C1 h00 hT ν c₂ c₃ _ hz Qs hlen hQ
/-- (C4) at every lattice point, from the lattice check. -/
theorem checkLattice4_sound {Z : List IPt} (hZ : okPts Z = true)
(h00 : ∀ ν, init p₂ p₃ y ϖ₂ ϖ₃ ν 0 0 ∈ ê ^ (1 + ν) • PZ (finsetOf Z))
{T : List ((ℕ × ℕ × ℕ) × Unit)} (hT : ∀ e ∈ T, LeafFact Z e)
{wit : List (List ℕ)} (h : checkLattice4 T wit = true) :
∀ ν, 2 ≤ ν → ν ≤ νE → d₃ ν ≤ 1 →
(∀ c₃, 1 ≤ c₃ → c₃ ≤ ν - 1 → init p₂ p₃ y ϖ₂ ϖ₃ ν 0 c₃ ∈ ê ^ (1 + ν) • PZ (finsetOf Z)) ∧
(d₂ ν ≤ 1 → ∀ c₂ c₃, 1 ≤ c₂ → c₂ + c₃ ≤ ν - 1 →
init p₂ p₃ y ϖ₂ ϖ₃ ν c₂ c₃ ∈ ê ^ (1 + ν) • PZ (finsetOf Z)) := by
intro ν h2 hνE hd
have hν36 : ν ≤ 36 := by simpa [νE] using hνE
have h4 : 4 ≤ ν := by
unfold d₃ at hd
split_ifs at hd <;> omega
have hlat : ∀ c₂ c₃, 1 ≤ c₂ + c₃ → c₂ + c₃ ≤ ν - 1 →
init p₂ p₃ y ϖ₂ ϖ₃ ν c₂ c₃ ∈ ê ^ (1 + ν) • PZ (finsetOf Z) := by
intro c₂ c₃ hc1 hc2
obtain ⟨dat, hok⟩ := rsc4_dat h (mem_lattice4 h4 hν36 hc1 hc2)
exact rsc4_point h00 hT ν c₂ c₃ dat hok
exact ⟨fun c₃ h1 h2' => hlat 0 c₃ (by omega) (by omega),
fun _ c₂ c₃ h1 h2' => hlat c₂ c₃ (by omega) h2'⟩
/-! ### Aggregation helpers (used by the generated `RSCData.All`) -/
theorem forall_mem_append' {α : Type} {P : α → Prop} {l₁ l₂ : List α}
(h₁ : ∀ e ∈ l₁, P e) (h₂ : ∀ e ∈ l₂, P e) : ∀ e ∈ l₁ ++ l₂, P e := by
intro e he
rcases List.mem_append.1 he with h | h
· exact h₁ e h
· exact h₂ e h
theorem forall_lt_of_forall_range {P : ℕ → Prop} {n : ℕ} (h : List.Forall P (List.range n)) :
∀ r < n, P r := by
intro r hr
exact List.forall_iff_forall_mem.1 h r (List.mem_range.2 hr)
theorem agg_getD_okPts : ∀ (l : List (List IPt)) (i : ℕ), l.all okPts = true → okPts (l.getD i []) = true
| [], i, _ => by simp [okPts]
| a :: l, 0, h => by
simp only [List.all_cons, Bool.and_eq_true] at h
simpa using h.1
| a :: l, i + 1, h => by
simp only [List.all_cons, Bool.and_eq_true] at h
simpa using agg_getD_okPts l i h.2
theorem agg_stage_aux {Z X Yt : List IPt} (hZ : checkZ Z = true) (hX : okPts X = true)
(hYt : okPts Yt = true) (N : ℕ) (hN : (X.length + 7) / 8 ≤ N)
(h : ∀ r < N, ∃ c, checkBlock Yt.length (chunks32 Yt) Z ((X.drop (8 * r)).take 8) c = true) :
StageFact Z X Yt := by
unfold StageFact
refine cover_blocks (fun x => ∀ z ∈ Z, merge p₂ p₃ (val x) (val z) ∈
convexHull ℝ (finsetOf Yt : Set (Fin 8 → ℝ)) + Kpos) X 8 (by norm_num) ?_
intro r hr x hx
obtain ⟨c, hcb⟩ := h r (by omega)
have hsub : ∀ y ∈ (X.drop (8 * r)).take 8, y ∈ X :=
fun y hy => List.mem_of_mem_drop (List.mem_of_mem_take hy)
have := checkBlock_sound hYt (checkZ_okPts hZ) (okPts_of_subset hX hsub) hcb
unfold StageFact at this
exact this x hx
theorem c1_of_blocks {Z : List IPt} (hZ : checkZ Z = true)
(h : List.Forall (fun r => ∃ c, checkBlock Z.length (chunks32 Z) Z ((Z.drop (8 * r)).take 8) c = true)
(List.range 128)) :
∀ z ∈ finsetOf Z, ∀ z' ∈ finsetOf Z, merge p₂ p₃ z z' ∈ PZ (finsetOf Z) := by
have hS : StageFact Z Z Z := agg_stage_aux hZ (checkZ_okPts hZ) (checkZ_okPts hZ) 128
(by have := checkZ_length hZ; omega) (forall_lt_of_forall_range h)
unfold StageFact at hS
intro z hz z' hz'
obtain ⟨x, hx, rfl⟩ := fam_mem_finsetOf.1 hz
obtain ⟨x', hx', rfl⟩ := fam_mem_finsetOf.1 hz'
exact hS x hx x' hx'
theorem stage_of_blocks {Z X Yt : List IPt} (hZ : checkZ Z = true) (hX : okPts X = true)
(hYt : okPts Yt = true) (nb : ℕ) (hnb : decide ((X.length + 7) / 8 ≤ nb) = true)
(h : List.Forall (fun r => ∃ c, checkBlock Yt.length (chunks32 Yt) Z ((X.drop (8 * r)).take 8) c = true)
(List.range nb)) : StageFact Z X Yt :=
agg_stage_aux hZ hX hYt nb (of_decide_eq_true hnb) (forall_lt_of_forall_range h)
theorem stage_X_ok {stages : List (List IPt)} (hst : stages.all okPts = true) (key : ℕ × ℕ × ℕ)
(i : ℕ) : okPts (([initI key.1 key.2.1 key.2.2] :: stages).getD i []) = true := by
rcases i with _ | i
· simp [okPts, okPt_initI]
· simpa using agg_getD_okPts stages i hst
theorem stage_Yt_ok {Z : List IPt} (hZ : checkZ Z = true) {stages : List (List IPt)}
(hst : stages.all okPts = true) (i : ℕ) : okPts ((stages ++ [Z]).getD i []) = true := by
have hall : (stages ++ [Z]).all okPts = true := by
simp only [List.all_append, Bool.and_eq_true, List.all_cons, List.all_nil, Bool.and_true]
exact ⟨hst, checkZ_okPts hZ⟩
exact agg_getD_okPts _ i hall
theorem chain1_table {Z : List IPt} (hZ : checkZ Z = true)
{es : List ((ℕ × ℕ × ℕ) × List (List (ℕ × ℕ × ℕ)))}
(h : checkChain1 Z.length (chunks32 Z) Z es = true) :
∀ e ∈ es.map (fun e => (e.1, 1)), ChainFact Z e := by
intro e he
obtain ⟨e0, he0, rfl⟩ := List.mem_map.1 he
exact checkChain1_sound (checkZ_okPts hZ) h e0 he0
theorem chain_stages_table {Z : List IPt} (hZ : checkZ Z = true) (key : ℕ × ℕ × ℕ)
(stages : List (List IPt)) (hst : stages.all okPts = true)
(hfacts : List.Forall (fun i => StageFact Z (([initI key.1 key.2.1 key.2.2] :: stages).getD i [])
((stages ++ [Z]).getD i [])) (List.range (stages.length + 1))) :
∀ e ∈ [(key, stages.length + 1)], ChainFact Z e := by
obtain ⟨ν, c₂, c₃⟩ := key
intro e he
rw [List.mem_singleton] at he
subst he
exact chainFact_of_stages (checkZ_okPts hZ) ν c₂ c₃ stages
(fun Y hY => List.all_eq_true.1 hst Y hY)
(fun i hi => forall_lt_of_forall_range hfacts i hi)
theorem leaf_table {Z : List IPt} (hZ : checkZ Z = true)
{es : List ((ℕ × ℕ × ℕ) × List (ℕ × ℕ × ℕ))}
(h : checkLeaves Z.length (chunks32 Z) es = true) :
∀ e ∈ es.map (fun e => (e.1, ())), LeafFact Z e := by
intro e he
obtain ⟨e0, he0, rfl⟩ := List.mem_map.1 he
exact checkLeaves_sound (checkZ_okPts hZ) h e0 he0
end
end MaxLeafFormal.RSCCheck
Back to top