hex

8.8. Proofs and Mathlib🔗

There is no HexPolyFastTheory. The theorems above say that each fast operation agrees with a HexPoly or HexTruncatedSeries operation, or describe its result by evaluation, divisibility and degree, and HexPolyTheory translates those into statements about Mathlib's Polynomial. For example, the interpolation plan computes Mathlib's Lagrange interpolant Lagrange.interpolate:

open Hex Hex.DensePoly HexPolyTheory Polynomial namespace HexPolyFastChapterTheory variable (plan : InterpPlan ℚ) /-- The `i`th point of an interpolation plan. -/ def node (i : Fin plan.size) : ℚ := plan.points[i.1]'(plan:InterpPlan ℚi:Fin plan.size⊢ ↑i < plan.points.size All goals completed! 🐙) theorem node_injective : Function.Injective (node plan) := plan:InterpPlan ℚ⊢ Function.Injective (node plan) plan:InterpPlan ℚi:Fin plan.sizej:Fin plan.sizehij:node plan i = node plan j⊢ i = j plan:InterpPlan ℚi:Fin plan.sizej:Fin plan.sizehij:node plan i = node plan jhne:¬i = j⊢ False plan:InterpPlan ℚi:Fin plan.sizej:Fin plan.sizehij:node plan i = node plan jhne:¬i = jys:Array ℚ := Array.ofFn fun k => if k = i then 1 else 0⊢ False plan:InterpPlan ℚi:Fin plan.sizej:Fin plan.sizehij:node plan i = node plan jhne:¬i = jys:Array ℚ := Array.ofFn fun k => if k = i then 1 else 0hsize:ys.size = plan.size⊢ False plan:InterpPlan ℚi:Fin plan.sizej:Fin plan.sizehij:node plan i = node plan jhne:¬i = jys:Array ℚ := Array.ofFn fun k => if k = i then 1 else 0hsize:ys.size = plan.sizep:DensePoly ℚhp:plan.interpolate? ys = some p⊢ False plan:InterpPlan ℚi:Fin plan.sizej:Fin plan.sizehij:node plan i = node plan jhne:¬i = jys:Array ℚ := Array.ofFn fun k => if k = i then 1 else 0hsize:ys.size = plan.sizep:DensePoly ℚhp:plan.interpolate? ys = some phi:p.eval plan.points[↑i] = ys.getD (↑i) 0⊢ False plan:InterpPlan ℚi:Fin plan.sizej:Fin plan.sizehij:node plan i = node plan jhne:¬i = jys:Array ℚ := Array.ofFn fun k => if k = i then 1 else 0hsize:ys.size = plan.sizep:DensePoly ℚhp:plan.interpolate? ys = some phi:p.eval plan.points[↑i] = ys.getD (↑i) 0hj:p.eval plan.points[↑j] = ys.getD (↑j) 0⊢ False plan:InterpPlan ℚi:Fin plan.sizej:Fin plan.sizehij:node plan i = node plan jhne:¬i = jys:Array ℚ := Array.ofFn fun k => if k = i then 1 else 0hsize:ys.size = plan.sizep:DensePoly ℚhp:plan.interpolate? ys = some phi:p.eval plan.points[↑i] = ys.getD (↑i) 0hj:p.eval plan.points[↑j] = ys.getD (↑j) 0hij':plan.points[↑i] = plan.points[↑j]⊢ False plan:InterpPlan ℚi:Fin plan.sizej:Fin plan.sizehij:node plan i = node plan jhne:¬i = jys:Array ℚ := Array.ofFn fun k => if k = i then 1 else 0hsize:ys.size = plan.sizep:DensePoly ℚhp:plan.interpolate? ys = some phi:ys.getD (↑j) 0 = ys.getD (↑i) 0hj:p.eval plan.points[↑j] = ys.getD (↑j) 0hij':plan.points[↑i] = plan.points[↑j]⊢ False All goals completed! 🐙 theorem interpolate?_eq_lagrange (ys : Array ℚ) (p : DensePoly ℚ) (h : plan.interpolate? ys = some p) : toPolynomial p = Lagrange.interpolate Finset.univ (node plan) (fun i => ys.getD i 0) := plan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some p⊢ toPolynomial p = (Lagrange.interpolate Finset.univ (node plan)) fun i => ys.getD (↑i) 0 plan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0⊢ toPolynomial p = (Lagrange.interpolate Finset.univ (node plan)) fun i => ys.getD (↑i) 0 plan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0⊢ Set.InjOn (node plan) ↑Finset.univplan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0⊢ (toPolynomial p).degree < ↑Finset.univ.cardplan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0⊢ ∀ i ∈ Finset.univ, Polynomial.eval (node plan i) (toPolynomial p) = ys.getD (↑i) 0 plan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0⊢ Set.InjOn (node plan) ↑Finset.univ All goals completed! 🐙 plan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0⊢ (toPolynomial p).degree < ↑Finset.univ.card plan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0⊢ ∀ (m : ℕ), plan.size ≤ m → (toPolynomial p).coeff m = 0 plan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0m:ℕhm:plan.size ≤ m⊢ (toPolynomial p).coeff m = 0 plan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0m:ℕhm:plan.size ≤ m⊢ p.coeff m = 0 exact coeff_eq_zero_of_size_le p (plan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0m:ℕhm:plan.size ≤ m⊢ p.size ≤ m All goals completed! 🐙) plan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0⊢ ∀ i ∈ Finset.univ, Polynomial.eval (node plan i) (toPolynomial p) = ys.getD (↑i) 0 plan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0i:Fin plan.sizea✝:i ∈ Finset.univ⊢ Polynomial.eval (node plan i) (toPolynomial p) = ys.getD (↑i) 0 plan:InterpPlan ℚys:Array ℚp:DensePoly ℚh:plan.interpolate? ys = some phsize:p.size ≤ plan.sizeheval:∀ (i : ℕ) (hi : i < plan.size), p.eval plan.points[i] = ys.getD i 0i:Fin plan.sizea✝:i ∈ Finset.univ⊢ p.eval (node plan i) = ys.getD (↑i) 0 All goals completed! 🐙 end HexPolyFastChapterTheory

The proof that the points of a plan are distinct uses only the public theorems: if two points were equal, the values 1 and 0 at them could not both be interpolated.