@@ -25,6 +25,8 @@ and a monomial order `m : MonomialOrder σ`.
2525
2626* `m.leadingTerm f` is the leading term of `f` for the monomial ordering `m`.
2727
28+ * `m.sPolynomial f g` is S-polynomial of `f` and `g`.
29+
2830* `m.leadingCoeff_ne_zero_iff f` asserts that this coefficient is nonzero iff `f ≠ 0`.
2931
3032* in a field, `m.isUnit_leadingCoeff f` asserts that this coefficient is a unit iff `f ≠ 0`.
@@ -693,6 +695,45 @@ section Ring
693695
694696variable {R : Type *} [CommRing R]
695697
698+ variable (m) in
699+ /-- The S-polynomial of two polynomials.
700+
701+ Denoting
702+
703+ - the leading monomial of polynomial $f$ and $g$ as $lm(f)$ and $lm(g)$,
704+ - the leading coefficient of $f$ and $g$ as $lc(f)$ and $lc(g)$
705+ (formalized as `m.leadingCoeff f` and `m.leadingCoeff g`), and
706+ - the least common multiple of $lm(f)$ and $lm(g)$ as $lcm(lm(f),lm(g))$,
707+
708+ the S-polynomial of $f$ and $g$ is defined as
709+ $$sPoly(f,g) := (lcm(lm(f),lm(g)) / lm(f)) * lc(g) * f - (lcm(lm(f),lm(g)) / lm(g)) * lc(f) * g.$$
710+
711+ $(lcm(lm(f),lm(g)) / lm(f))$ and $lcm(lm(f),lm(g)) / lm(g)$ is formalized as
712+ `monomial (m.degree g - m.degree f) 1` and `monomial (m.degree g - m.degree f) 1`, while there is
713+ also another more direct formalization in `sPolynomial_def`.
714+
715+ Notice that, when the polynomial ring is over a field, S-polynomial is usually defined as
716+ $$sPoly'(f,g) :=
717+ (lcm(lm(f),lm(g)) / (lm(f) * lc(f))) * f - (lcm(lm(f),lm(g)) / (lm(g) * lc(g))) * g,$$
718+ while we avoid inverting $lc(f)$ and $lc(g)$ in this formalization so that it doesn't require a
719+ field or units (`IsUnit`) over ring.
720+
721+ An equality between these two versions holds: $$sPoly(f,g) = lc(f) * lc(g) * sPoly'(f,g).$$
722+ -/
723+ noncomputable def sPolynomial (f g : MvPolynomial σ R) : MvPolynomial σ R :=
724+ monomial (m.degree g - m.degree f) (m.leadingCoeff g) * f -
725+ monomial (m.degree f - m.degree g) (m.leadingCoeff f) * g
726+
727+ lemma sPolynomial_def (f g : MvPolynomial σ R) :
728+ m.sPolynomial f g =
729+ monomial (m.degree f ⊔ m.degree g - m.degree f) (m.leadingCoeff g) * f -
730+ monomial (m.degree f ⊔ m.degree g - m.degree g) (m.leadingCoeff f) * g := by
731+ suffices ∀ f g, m.degree g - m.degree f = m.degree f ⊔ m.degree g - m.degree f by
732+ rw [sPolynomial, this, this, sup_comm]
733+ intro f g
734+ ext a
735+ obtain (h|h) := le_total (m.degree f a) (m.degree g a) <;> simp [h]
736+
696737lemma degree_ne_zero_of_sub_leadingTerm_ne_zero {f : MvPolynomial σ R}
697738 (h : f - m.leadingTerm f ≠ 0 ) : m.degree f ≠ 0 := by
698739 contrapose! h
@@ -751,6 +792,127 @@ theorem degree_sub_leadingTerm_lt_iff {f : MvPolynomial σ R} :
751792 simp only [h', map_zero] at h
752793 exact not_lt_bot h
753794
795+ lemma sPolynomial_antisymm (f g : MvPolynomial σ R) :
796+ m.sPolynomial f g = - m.sPolynomial g f :=
797+ (neg_sub (_ * g) (_ * f)).symm
798+
799+ @[simp]
800+ lemma sPolynomial_left_zero (g : MvPolynomial σ R) :
801+ m.sPolynomial 0 g = 0 := by
802+ simp [sPolynomial]
803+
804+ @[simp]
805+ lemma sPolynomial_right_zero (f : MvPolynomial σ R) :
806+ m.sPolynomial f 0 = 0 := by
807+ rw [sPolynomial_antisymm, sPolynomial_left_zero, neg_zero]
808+
809+ @[simp]
810+ lemma sPolynomial_self (f : MvPolynomial σ R) : m.sPolynomial f f = 0 := sub_self _
811+
812+ lemma degree_sPolynomial_le (f g : MvPolynomial σ R) :
813+ ((m.degree <| m.sPolynomial f g) ≼[m] m.degree f ⊔ m.degree g) := by
814+ classical
815+ wlog h0 : f ≠ 0 ∧ g ≠ 0
816+ · (obtain rfl|rfl : f = 0 ∨ g = 0 := by tauto) <;> simp
817+ simp only [sPolynomial_def]
818+ apply degree_sub_le.trans
819+ apply (sup_le_sup degree_mul_le degree_mul_le).trans
820+ simp [degree_monomial, h0.1 , h0.2 , tsub_add_cancel_of_le, le_sup_left, le_sup_right]
821+
822+ lemma coeff_sPolynomial_sup_eq_zero (f g : MvPolynomial σ R) :
823+ (m.sPolynomial f g).coeff (m.degree f ⊔ m.degree g) = 0 := by
824+ rw [sPolynomial_def, coeff_sub]
825+ nth_rewrite 1 [← tsub_add_cancel_of_le le_sup_left, coeff_monomial_mul]
826+ nth_rewrite 1 [← tsub_add_cancel_of_le le_sup_right, coeff_monomial_mul]
827+ unfold leadingCoeff
828+ ring
829+
830+ lemma degree_sPolynomial (f g : MvPolynomial σ R) :
831+ (m.degree <| m.sPolynomial f g) ≺[m] m.degree f ⊔ m.degree g ∨ m.sPolynomial f g = 0 := by
832+ by_cases hf : m.degree f = 0 ∧ m.degree g = 0
833+ · rcases hf with ⟨h₁, h₂⟩
834+ right
835+ suffices C (m.leadingCoeff g) * f - C (m.leadingCoeff f) * g = 0 by simp_all [sPolynomial_def]
836+ nth_rewrite 1 [degree_eq_zero_iff.mp h₁]
837+ nth_rewrite 2 [degree_eq_zero_iff.mp h₂]
838+ ring
839+ · rw [or_iff_not_imp_right]
840+ intro hs
841+ apply (m.degree_sPolynomial_le f g).lt_of_ne
842+ apply m.toSyn.injective.ne
843+ contrapose! hs
844+ rw [← m.coeff_degree_eq_zero_iff, hs, m.coeff_sPolynomial_sup_eq_zero]
845+
846+ lemma degree_sPolynomial_lt_sup_degree {f g : MvPolynomial σ R} (h : m.sPolynomial f g ≠ 0 ) :
847+ (m.degree <| m.sPolynomial f g) ≺[m] m.degree f ⊔ m.degree g :=
848+ (or_iff_left h).mp <| m.degree_sPolynomial f g
849+
850+ lemma sPolynomial_lt_of_degree_ne_zero_of_degree_eq {f g : MvPolynomial σ R}
851+ (h : m.degree f = m.degree g) (hs : m.sPolynomial f g ≠ 0 ) :
852+ m.degree (m.sPolynomial f g) ≺[m] m.degree f := by
853+ simpa [h] using m.degree_sPolynomial_lt_sup_degree hs
854+
855+ lemma sPolynomial_mul_monomial [IsCancelMulZero R] (p₁ p₂ : MvPolynomial σ R) (d₁ d₂ : σ →₀ ℕ)
856+ (c₁ c₂ : R) :
857+ m.sPolynomial ((monomial d₁ c₁) * p₁) ((monomial d₂ c₂) * p₂) =
858+ monomial ((d₁ + m.degree p₁) ⊔ (d₂ + m.degree p₂) - m.degree p₁ ⊔ m.degree p₂) (c₁ * c₂) *
859+ m.sPolynomial p₁ p₂ := by
860+ classical
861+ simp only [sPolynomial_def]
862+ by_cases! H : c₁ = 0 ∨ c₂ = 0 ∨ p₁ = 0 ∨ p₂ = 0
863+ · (obtain rfl | rfl | rfl | rfl := H) <;> simp
864+ rcases H with ⟨hc1, hc2, hp1, hp2⟩
865+ have hm1 := (monomial_eq_zero (s := d₁)).not.mpr hc1
866+ have hm2 := (monomial_eq_zero (s := d₂)).not.mpr hc2
867+ simp_rw [m.degree_mul hm1 hp1, m.degree_mul hm2 hp2,
868+ mul_sub, ← mul_assoc _ _ p₁, ← mul_assoc _ _ p₂, monomial_mul,
869+ m.leadingCoeff_mul hm1 hp1, m.leadingCoeff_mul hm2 hp2, m.leadingCoeff_monomial,
870+ degree_monomial, hc1, hc2, reduceIte, mul_right_comm, mul_comm c₂ c₁]
871+ rw [tsub_add_tsub_cancel (sup_le_sup (self_le_add_left _ _) (self_le_add_left _ _)) (by simp),
872+ tsub_add_tsub_cancel (sup_le_sup (self_le_add_left _ _) (self_le_add_left _ _)) (by simp),
873+ tsub_add_eq_add_tsub le_sup_left, tsub_add_eq_add_tsub le_sup_right,
874+ add_comm d₁, add_comm d₂, add_tsub_add_eq_tsub_right, add_tsub_add_eq_tsub_right]
875+
876+ lemma sPolynomial_decomposition {d : m.syn} {ι : Type *}
877+ {B : Finset ι} {g : ι → MvPolynomial σ R}
878+ (hd : ∀ b ∈ B,
879+ (m.toSyn <| m.degree <| g b) = d ∧ IsUnit (m.leadingCoeff <| g b) ∨ g b = 0 )
880+ (hfd : (m.toSyn <| m.degree <| ∑ b ∈ B, g b) < d) :
881+ ∃ (c : ι → ι → R),
882+ ∑ b ∈ B, g b = ∑ b₁ ∈ B, ∑ b₂ ∈ B, (c b₁ b₂) • m.sPolynomial (g b₁) (g b₂) := by
883+ classical
884+ induction B using Finset.induction_on with
885+ | empty => simp
886+ | insert b B hb h =>
887+ by_cases hb0 : g b = 0
888+ · simp_all
889+ simp? [Finset.sum_insert hb, hb0] at hfd hd says
890+ simp only [Finset.sum_insert hb, Finset.mem_insert, forall_eq_or_imp, hb0, or_false] at hfd hd
891+ obtain ⟨⟨rfl, isunit_gb⟩, hd⟩ := hd
892+ use fun b₁ b₂ ↦ if b₂ = b then ↑isunit_gb.unit⁻¹ else 0
893+ simp? [Finset.sum_insert hb, hb] says
894+ simp only [Finset.sum_insert hb, ite_smul, zero_smul, ↓reduceIte, Finset.sum_ite_eq', hb,
895+ add_zero, sPolynomial_self, smul_zero, zero_add]
896+ simp only [m.toSyn.injective.eq_iff] at *
897+ trans ∑ b' ∈ B, (g b' - (m.leadingCoeff (g b') * ↑isunit_gb.unit⁻¹) • g b)
898+ · suffices (-(∑ i ∈ B, m.leadingCoeff (g i))) = m.leadingCoeff (g b) by
899+ rw [add_comm, Finset.sum_sub_distrib, sub_eq_add_neg, ← Finset.sum_smul, ← Finset.sum_mul,
900+ ← neg_smul, ← neg_mul, this, isunit_gb.mul_val_inv, one_smul]
901+ rw [← add_eq_zero_iff_neg_eq']
902+ trans (g b).coeff (m.degree <| g b) + ∑ i ∈ B, (g i).coeff (m.degree <| g b)
903+ · unfold leadingCoeff
904+ congr 1
905+ apply Finset.sum_congr rfl
906+ intro b' hb'
907+ rcases hd b' hb' with h | h <;> simp [h]
908+ · rw [← coeff_sum, ← coeff_add, ← notMem_support_iff]
909+ exact m.notMem_support_of_degree_lt hfd
910+ · apply Finset.sum_congr rfl
911+ intro b' hb'
912+ rw [sPolynomial]
913+ obtain (⟨h, -⟩ | h) := hd b' hb' <;>
914+ simp [h, ← smul_eq_C_mul, smul_sub, ← mul_smul, mul_comm (m.leadingCoeff (g b'))]
915+
754916end Ring
755917
756918section Field
@@ -761,6 +923,15 @@ theorem isUnit_leadingCoeff {f : MvPolynomial σ R} :
761923 IsUnit (m.leadingCoeff f) ↔ f ≠ 0 := by
762924 simp only [isUnit_iff_ne_zero, ne_eq, leadingCoeff_eq_zero_iff]
763925
926+ lemma sPolynomial_decomposition' {d : m.syn} {ι : Type *}
927+ {B : Finset ι} (g : ι → MvPolynomial σ R)
928+ (hd : ∀ b ∈ B, (m.toSyn <| m.degree <| g b) = d ∨ g b = 0 )
929+ (hfd : (m.toSyn <| m.degree <| ∑ b ∈ B, g b) < d) :
930+ ∃ (c : ι → ι → R),
931+ ∑ b ∈ B, g b = ∑ b₁ ∈ B, ∑ b₂ ∈ B, (c b₁ b₂) • m.sPolynomial (g b₁) (g b₂) := by
932+ refine m.sPolynomial_decomposition ?_ hfd
933+ simpa [and_or_right, em']
934+
764935end Field
765936
766937section Binomial
0 commit comments