@@ -141,3 +141,43 @@ lemma prob_eval_zero_le_div
141141 · convert congr_arg₂ (· * ·) (card_filter_eval_subtype_eq_piFinset S f) rfl
142142 · rw [Fintype.card_pi]
143143 aesop
144+
145+ section ZeroCount
146+
147+ open Finset
148+
149+ /-- Counting Schwartz-Zippel over all of a finite field: a nonzero polynomial in `s` variables of
150+ total degree at most `D` has at most `D * |F| ^ (s - 1)` zeros in `Fin s → F`. -/
151+ theorem MvPolynomial.card_zeros_le_of_totalDegree_le_fin
152+ {F : Type *} [Field F] [Fintype F] [DecidableEq F] {s : ℕ}
153+ (f : MvPolynomial (Fin s) F) (hf : f ≠ 0 ) {D : ℕ} (hd : f.totalDegree ≤ D) :
154+ #{x : Fin s → F | MvPolynomial.eval x f = 0 } ≤ D * Fintype.card F ^ (s - 1 ) := by
155+ classical
156+ have hq : 0 < Fintype.card F := Fintype.card_pos
157+ have key := schwartz_zippel_counting f hf (fun _ => Finset.univ) D (Fintype.card F) hd hq
158+ (fun i => by simp)
159+ simp only [Fintype.piFinset_univ, Finset.card_univ, Finset.prod_const] at key
160+ match s with
161+ | 0 => simpa using le_trans (Nat.le_mul_of_pos_right _ hq) (by simpa using key)
162+ | (t + 1 ) =>
163+ refine Nat.le_of_mul_le_mul_right ?_ hq
164+ simpa [pow_succ, mul_assoc] using key
165+
166+ /-- Counting Schwartz-Zippel over all of a finite field, for an arbitrary finite index type of
167+ variables: a nonzero polynomial in the variables `ι` of total degree at most `D` has at most
168+ `D * |F| ^ (|ι| - 1)` zeros in `ι → F`. -/
169+ theorem MvPolynomial.card_zeros_le_of_totalDegree_le
170+ {F : Type *} [Field F] [Fintype F] [DecidableEq F] {ι : Type *} [Fintype ι] [DecidableEq ι]
171+ (f : MvPolynomial ι F) (hf : f ≠ 0 ) {D : ℕ} (hd : f.totalDegree ≤ D) :
172+ #{x : ι → F | MvPolynomial.eval x f = 0 } ≤ D * Fintype.card F ^ (Fintype.card ι - 1 ) := by
173+ classical
174+ set e := Fintype.equivFin ι
175+ have hg : MvPolynomial.rename (e : ι → Fin (Fintype.card ι)) f ≠ 0 := fun h =>
176+ hf (MvPolynomial.rename_injective _ e.injective (by simpa using h))
177+ have hgd : (MvPolynomial.rename (e : ι → Fin (Fintype.card ι)) f).totalDegree ≤ D :=
178+ le_trans (MvPolynomial.totalDegree_rename_le _ _) hd
179+ refine le_trans (le_of_eq ?_) (MvPolynomial.card_zeros_le_of_totalDegree_le_fin _ hg hgd)
180+ refine Finset.card_nbij' (fun x => x ∘ e.symm) (fun y => y ∘ e) ?_ ?_ ?_ ?_ <;>
181+ intro x hx <;> simp_all [MvPolynomial.eval_rename, Function.comp_assoc]
182+
183+ end ZeroCount
0 commit comments