MaxLeafFormal.RSCCheckExtras
Source file MaxLeafFormal/RSCCheckExtras.lean of the Lean project (how it is built).
import MaxLeafFormal.RSCCheck
import MaxLeafFormal.RSCStages
/-!
# Checkers for the exact `c_Z` and the stage sets
`checkCZ` and `checkStages` are computable Boolean checkers over the exported data of `RSCData`; the
generated shard theorems of `MaxLeafFormal.RSCData.Extras.Shards` decide them by `native_decide`.
Their soundness theorems, and the bridge `isStages_of_facts` from the stage facts of `RSCData`
to `RSCCert.IsStages`, are kernel-checked and use no data.
-/
namespace MaxLeafFormal.RSCCheck
/-! ### Computable checkers -/
/-- `fin` attains its minimum `a / b` over `Z` at index `k` (all cross-multiplied):
`b · finN(N_k) = a · 2000 D_k` and `a · 2000 D ≤ b · finN(N)` for every point `(N, D)`. -/
def checkCZ (Z : List IPt) (k a b : ℕ) : Bool :=
okPts Z && decide (k < Z.length) && decide (0 < b) &&
decide (b * finN (Z.getD k zeroI).1 = a * (2000 * (Z.getD k zeroI).2)) &&
Z.all (fun P => decide (a * (2000 * P.2) ≤ b * finN P.1))
/-- Each stage list has the given length, well-formed points, and strictly increasing values. -/
def checkStages : List (List IPt) → List ℕ → Bool
| [], [] => true
| Y :: Ys, n :: ns => (Y.length == n) && okPts Y && sortedZ Y && checkStages Ys ns
| _, _ => false
open MaxLeafFormal.RSCCert MaxLeafFormal.RSCParams
open MaxLeafFormal.Antinorm8 (Kpos PZ)
open Pointwise
noncomputable section
/-! ### Soundness -/
theorem fin_val {P : IPt} (h : okPt P = true) :
Antinorm8.fin p₂ (val P) = (finN P.1 : ℝ) / (2000 * (P.2 : ℝ)) := by
have hDpos : 0 < P.2 := okPt_pos h
have hL : P.1.length = 8 := by
simp only [okPt, Bool.and_eq_true, beq_iff_eq] at h
exact h.1
obtain ⟨L, D⟩ := P
obtain ⟨N0, N1, N2, N3, N4, N5, N6, N7, rfl⟩ := list8_of_length hL
have hD0 : (D : ℝ) ≠ 0 := by exact_mod_cast hDpos.ne'
simp only [finN]
push_cast
rw [p2v]
simp [Antinorm8.fin, val]
field_simp
ring
theorem nodup_val_of_sorted {Y : List IPt} (hok : okPts Y = true) (hs : sortedZ Y = true) :
(Y.map val).Nodup := by
have hokL : ∀ P ∈ Y, okPt P = true := by
simp only [okPts, List.all_eq_true] at hok
exact hok
have hpos : ∀ P ∈ Y, 0 < P.2 := fun P hP => okPt_pos (hokL P hP)
have hnV := nodup_vlist hpos hs
have hY : Y.Nodup := List.Nodup.of_map vlist hnV
refine List.Nodup.map_on ?_ hY
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 card_finsetOf_of_sorted {Y : List IPt} (hok : okPts Y = true) (hs : sortedZ Y = true) :
(finsetOf Y).card = Y.length := by
unfold finsetOf
rw [List.toFinset_card_of_nodup (nodup_val_of_sorted hok hs), List.length_map]
theorem checkCZ_sound {Z : List IPt} {k a b : ℕ} (h : checkCZ Z k a b = true)
(hne : (finsetOf Z).Nonempty) : Antinorm8.cZ p₂ (finsetOf Z) hne = (a : ℝ) / (b : ℝ) := by
simp only [checkCZ, Bool.and_eq_true, decide_eq_true_eq, List.all_eq_true] at h
obtain ⟨⟨⟨⟨hok, hk⟩, hb⟩, heq⟩, hall⟩ := h
have hokL : ∀ P ∈ Z, okPt P = true := by
simp only [okPts, List.all_eq_true] at hok
exact hok
have hbr : (0 : ℝ) < b := by exact_mod_cast hb
have hmemk : Z.getD k zeroI ∈ Z := by
rw [List.getD_eq_getElem _ _ hk]
exact List.getElem_mem hk
unfold Antinorm8.cZ
apply le_antisymm
· have h1 : val (Z.getD k zeroI) ∈ finsetOf Z := fam_mem_finsetOf.2 ⟨_, hmemk, rfl⟩
refine (Finset.inf'_le _ h1).trans (le_of_eq ?_)
have hok' := hokL _ hmemk
have hD : (0 : ℝ) < ((Z.getD k zeroI).2 : ℝ) := by exact_mod_cast okPt_pos hok'
rw [fin_val hok', div_eq_div_iff (mul_pos (by norm_num) hD).ne' hbr.ne']
have := congrArg (fun n : ℕ => (n : ℝ)) heq
push_cast at this
linarith
· apply Finset.le_inf'
intro z hz
obtain ⟨P, hP, rfl⟩ := fam_mem_finsetOf.1 hz
have hok' := hokL P hP
have hD : (0 : ℝ) < (P.2 : ℝ) := by exact_mod_cast okPt_pos hok'
rw [fin_val hok', div_le_div_iff₀ hbr (mul_pos (by norm_num) hD)]
have := hall P hP
have h' : ((a * (2000 * P.2) : ℕ) : ℝ) ≤ ((b * finN P.1 : ℕ) : ℝ) := by exact_mod_cast this
push_cast at h'
linarith
theorem checkStages_sound {stages : List (List IPt)} {ns : List ℕ}
(h : checkStages stages ns = true) :
stages.all okPts = true ∧ (stages.map finsetOf).map Finset.card = ns := by
induction stages generalizing ns with
| nil =>
cases ns with
| nil => simp
| cons n ns => simp [checkStages] at h
| cons Y Ys ih =>
cases ns with
| nil => simp [checkStages] at h
| cons n ns =>
simp only [checkStages, Bool.and_eq_true, beq_iff_eq] at h
obtain ⟨⟨⟨hl, hok⟩, hs⟩, hrest⟩ := h
obtain ⟨ih1, ih2⟩ := ih hrest
refine ⟨by simp [hok, ih1], ?_⟩
simp only [List.map_cons, ih2, card_finsetOf_of_sorted hok hs, hl]
theorem finsetOf_nil : finsetOf [] = ∅ := by
simp [finsetOf]
theorem finsetOf_initI (ν c₂ c₃ : ℕ) :
finsetOf [initI ν c₂ c₃] = {(ê ^ (1 + ν))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ ν c₂ c₃} := by
simp [finsetOf, val_initI]
theorem getD_map_finsetOf : ∀ (l : List (List IPt)) (n : ℕ),
(l.map finsetOf).getD n ∅ = finsetOf (l.getD n [])
| [], n => by simp [finsetOf_nil]
| a :: l, 0 => by simp
| a :: l, n + 1 => by simpa using getD_map_finsetOf l n
theorem isStages_of_facts {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))) :
RSCCert.IsStages p₂ p₃ (finsetOf Z)
((ê ^ (1 + key.1))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ key.1 key.2.1 key.2.2) (stages.map finsetOf) := by
have _hZ := hZ
have _hst := hst
refine ⟨?_, ?_⟩
· intro Y hY x hx
obtain ⟨S, -, rfl⟩ := List.mem_map.1 hY
obtain ⟨P, -, rfl⟩ := fam_mem_finsetOf.1 hx
exact ⟨val_nonneg P, fun s => ⟨((P.1.getD s 0 : ℕ) : ℚ) / (P.2 : ℚ), by simp [val]⟩⟩
· intro i hi1 hi2 x hx z hz
rw [List.length_map] at hi2
have hF := forall_lt_of_forall_range hfacts (i - 1) (by omega)
have e1 : (({(ê ^ (1 + key.1))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ key.1 key.2.1 key.2.2} :
Finset (Fin 8 → ℝ)) :: stages.map finsetOf) =
([initI key.1 key.2.1 key.2.2] :: stages).map finsetOf := by
rw [List.map_cons, finsetOf_initI]
have e2 : stages.map finsetOf ++ [finsetOf Z] = (stages ++ [Z]).map finsetOf := by
simp
rw [e1, getD_map_finsetOf] at hx
rw [e2, getD_map_finsetOf]
obtain ⟨X, hX, rfl⟩ := fam_mem_finsetOf.1 hx
obtain ⟨W, hW, rfl⟩ := fam_mem_finsetOf.1 hz
unfold StageFact at hF
exact hF X hX W hW
/-- A checked chain with one stage set of `n` points gives stages `[Y₁]` with `|Y₁| = n`. -/
theorem stages_one {Z : List IPt} (hZ : checkZ Z = true) (key : ℕ × ℕ × ℕ)
{stages : List (List IPt)} {n : ℕ} (hsz : checkStages stages [n] = 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))) :
∃ Y₁ : Finset (Fin 8 → ℝ), Y₁.card = n ∧
RSCCert.IsStages p₂ p₃ (finsetOf Z)
((ê ^ (1 + key.1))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ key.1 key.2.1 key.2.2) [Y₁] := by
obtain ⟨hst, hc⟩ := checkStages_sound hsz
have hS := isStages_of_facts hZ key hst hfacts
rcases hm : stages.map finsetOf with _ | ⟨Y, _ | ⟨Y', l⟩⟩
· rw [hm] at hc; simp at hc
· rw [hm] at hc hS
simp only [List.map_cons, List.map_nil, List.cons.injEq, and_true] at hc
exact ⟨Y, hc, hS⟩
· rw [hm] at hc; simp at hc
/-- A checked chain with two stage sets of `n₁`, `n₂` points gives stages `[Y₁, Y₂]`. -/
theorem stages_two {Z : List IPt} (hZ : checkZ Z = true) (key : ℕ × ℕ × ℕ)
{stages : List (List IPt)} {n₁ n₂ : ℕ} (hsz : checkStages stages [n₁, n₂] = 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))) :
∃ Y₁ Y₂ : Finset (Fin 8 → ℝ), Y₁.card = n₁ ∧ Y₂.card = n₂ ∧
RSCCert.IsStages p₂ p₃ (finsetOf Z)
((ê ^ (1 + key.1))⁻¹ • init p₂ p₃ y ϖ₂ ϖ₃ key.1 key.2.1 key.2.2) [Y₁, Y₂] := by
obtain ⟨hst, hc⟩ := checkStages_sound hsz
have hS := isStages_of_facts hZ key hst hfacts
rcases hm : stages.map finsetOf with _ | ⟨Y, _ | ⟨Y', _ | ⟨Y'', l⟩⟩⟩
· rw [hm] at hc; simp at hc
· rw [hm] at hc; simp at hc
· rw [hm] at hc hS
simp only [List.map_cons, List.map_nil, List.cons.injEq, and_true] at hc
exact ⟨Y, Y', hc.1, hc.2, hS⟩
· rw [hm] at hc; simp at hc
end
end MaxLeafFormal.RSCCheck
Back to top