1-- The remainder and factor theorems: dividing a polynomial by X − a leaves2-- the remainder p(a), and a is a root exactly when X − a divides p3-- Part of Cumulus, the Grace17 mathematics library.4-- Copyright (c) 2026 Grant Passmore.5-- Released under the Apache License 2.0. See LICENSE in the repository root.6-- Authors: Grant Passmore78module Grace.Cumulus.Algebra.Polynomial.FactorTheorem9import Horner1011section Rings12variable (A add zero neg mul one leading : Set)13notationring R := (A, add, zero, neg, mul, one)14hypothesisring : IsCommRing(R)15hypothesis initial : leading ∈ R1617-- The remainder theorem: p(x) = p(a) + (x − a)·q(x) with q the synthetic18-- quotient, so the remainder on division by X − a is p(a).19theorem remainder.theorem (a x c : Set) (cs : List(A))20requires center : a ∈ R21requires element : x ∈ R22requires coefficient : c ∈ R23shows hornerAt{A}(add, mul, leading, x, c :: cs) = R[hornerAt{A}(add, mul, leading, a, c :: cs) + (x - a) * hornerAt{A}(add, mul, leading, x, hornerQuotient{A}(add, mul, leading, a, cs))]24proof25exact hornerAt.synthetic_division with*2627-- The factor theorem: at a root a, X − a divides p with the synthetic quotient.28theorem factor.theorem (a x c : Set) (cs : List(A))29requires center : a ∈ R30requires element : x ∈ R31requires coefficient : c ∈ R32requires root : hornerAt{A}(add, mul, leading, a, c :: cs) = R[0]33shows hornerAt{A}(add, mul, leading, x, c :: cs) = R[(x - a) * hornerAt{A}(add, mul, leading, x, hornerQuotient{A}(add, mul, leading, a, cs))]34proof35have division := hornerAt.synthetic_division at A, add, zero, neg, mul, one, leading, a, x, c, cs with*36have quotient := hornerQuotient.closed at A, add, zero, neg, mul, one, leading, a, cs with*37have quotientValue := hornerAt.closed at A, add, zero, neg, mul, one, leading, x, hornerQuotient{A}(add, mul, leading, a, cs) with*38rw root at division39rw division40ring4142-- Conversely, a factor X − a forces a root at a.43theorem factor.root (a c : Set) (cs : List(A))44requires center : a ∈ R45requires coefficient : c ∈ R46requires factor : ∀ x ∈ R, hornerAt{A}(add, mul, leading, x, c :: cs) = R[(x - a) * hornerAt{A}(add, mul, leading, x, hornerQuotient{A}(add, mul, leading, a, cs))]47shows hornerAt{A}(add, mul, leading, a, c :: cs) = R[0]48proof49have quotient := hornerQuotient.closed at A, add, zero, neg, mul, one, leading, a, cs with*50have quotientValue := hornerAt.closed at A, add, zero, neg, mul, one, leading, a, hornerQuotient{A}(add, mul, leading, a, cs) with*51have atRoot := factor with center52rw atRoot53ring5455end Rings56