Skip to content

Commit acac8db

Browse files
authored
Add simp/grind lemmas for CMvPolynomial.eval (add/mul) (#45)
* Add simp/grind lemmas for CMvPolynomial.eval (add/mul) * fix: add copyright header to CMvPolynomialEvalLemmas.lean
1 parent d1b06c9 commit acac8db

2 files changed

Lines changed: 77 additions & 0 deletions

File tree

CompPoly.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import CompPoly.Multilinear.Basic
77
import CompPoly.Multilinear.Equiv
88
import CompPoly.Multivariate.CMvMonomial
99
import CompPoly.Multivariate.CMvPolynomial
10+
import CompPoly.Multivariate.CMvPolynomialEvalLemmas
1011
import CompPoly.Multivariate.Lawful
1112
import CompPoly.Multivariate.MvPolyEquiv
1213
import CompPoly.Multivariate.Unlawful
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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

Comments
 (0)