|
| 1 | +/- |
| 2 | +Copyright (c) 2025 CompPoly. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Frantisek Silvasi, Julian Sutherland, Andrei Burdușa |
| 5 | +-/ |
| 6 | + |
| 7 | +import CompPoly.Multivariate.MvPolyEquiv |
| 8 | + |
| 9 | +/-! |
| 10 | +# simp/grind lemmas for `CPoly.CMvPolynomial.eval` |
| 11 | +
|
| 12 | +These lemmas are meant to support proof automation (simp/grind normalization) |
| 13 | +when reasoning about polynomial evaluation (e.g. Horner correctness proofs). |
| 14 | +-/ |
| 15 | + |
| 16 | +namespace CPoly |
| 17 | + |
| 18 | +open CMvPolynomial |
| 19 | + |
| 20 | +section |
| 21 | + |
| 22 | +variable {n : ℕ} {R : Type} [CommSemiring R] [BEq R] [LawfulBEq R] |
| 23 | +variable (vals : Fin n → R) |
| 24 | + |
| 25 | +@[simp] |
| 26 | +lemma eval_add (p q : CMvPolynomial n R) : |
| 27 | + (p + q).eval vals = p.eval vals + q.eval vals := by |
| 28 | + -- rewrite both sides via Mathlib `MvPolynomial` using the equivalence |
| 29 | + have hpq : (p + q).eval vals = (fromCMvPolynomial (p + q)).eval vals := by |
| 30 | + simpa using (eval_equiv (p := p + q) (vals := vals)) |
| 31 | + have hp : (fromCMvPolynomial p).eval vals = p.eval vals := by |
| 32 | + simpa using (eval_equiv (p := p) (vals := vals)).symm |
| 33 | + have hq : (fromCMvPolynomial q).eval vals = q.eval vals := by |
| 34 | + simpa using (eval_equiv (p := q) (vals := vals)).symm |
| 35 | + |
| 36 | + calc |
| 37 | + (p + q).eval vals |
| 38 | + = (fromCMvPolynomial (p + q)).eval vals := hpq |
| 39 | + _ = (fromCMvPolynomial p + fromCMvPolynomial q).eval vals := by |
| 40 | + simp [map_add] |
| 41 | + _ = (fromCMvPolynomial p).eval vals + (fromCMvPolynomial q).eval vals := by |
| 42 | + -- Mathlib lemma |
| 43 | + simpa using (MvPolynomial.eval_add (p := fromCMvPolynomial p) |
| 44 | + (q := fromCMvPolynomial q) |
| 45 | + (x := vals)) |
| 46 | + _ = p.eval vals + q.eval vals := by |
| 47 | + simp [hp, hq] |
| 48 | + |
| 49 | +@[simp] |
| 50 | +lemma eval_mul (p q : CMvPolynomial n R) : |
| 51 | + (p * q).eval vals = p.eval vals * q.eval vals := by |
| 52 | + have hpq : (p * q).eval vals = (fromCMvPolynomial (p * q)).eval vals := by |
| 53 | + simpa using (eval_equiv (p := p * q) (vals := vals)) |
| 54 | + have hp : (fromCMvPolynomial p).eval vals = p.eval vals := by |
| 55 | + simpa using (eval_equiv (p := p) (vals := vals)).symm |
| 56 | + have hq : (fromCMvPolynomial q).eval vals = q.eval vals := by |
| 57 | + simpa using (eval_equiv (p := q) (vals := vals)).symm |
| 58 | + |
| 59 | + calc |
| 60 | + (p * q).eval vals |
| 61 | + = (fromCMvPolynomial (p * q)).eval vals := hpq |
| 62 | + _ = (fromCMvPolynomial p * fromCMvPolynomial q).eval vals := by |
| 63 | + simp [map_mul] |
| 64 | + _ = (fromCMvPolynomial p).eval vals * (fromCMvPolynomial q).eval vals := by |
| 65 | + -- Mathlib lemma |
| 66 | + simpa using (MvPolynomial.eval_mul (p := fromCMvPolynomial p) |
| 67 | + (q := fromCMvPolynomial q) |
| 68 | + (x := vals)) |
| 69 | + _ = p.eval vals * q.eval vals := by |
| 70 | + simp [hp, hq] |
| 71 | + |
| 72 | +end |
| 73 | + |
| 74 | +attribute [grind =] eval_add eval_mul |
| 75 | + |
| 76 | +end CPoly |
0 commit comments